Compare commits

..

No commits in common. "main" and "dev" have entirely different histories.
main ... dev

953 changed files with 305513 additions and 58 deletions

56
.gitignore vendored Normal file
View File

@ -0,0 +1,56 @@
######################################################################
# Build Tools
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### JRebel ###
rebel.xml
### NetBeans ###
nbproject/private/
build/*
nbbuild/
dist/
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
*.swp
!*/build/*.java
!*/build/*.html
!*/build/*.xml
bin/
ry.bat
ry.sh
run.sh
package.bat
sql/quartz.sql
**/application-local.yml

26
DirectoryV3.xml Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<trees>
<tree path="/cmvr-iot-system" title="系统模块"/>
<tree path="/cmvr-iot-admin" title="后台服务"/>
<tree path="/cmvr-iot-common" title="工具类"/>
<tree path="/cmvr-iot-framework" title="框架核心组件"/>
<tree path="/cmvr-iot-generator" title="代码生成"/>
<tree path="/cmvr-iot-quartz" title="定时任务"/>
<tree path="/cmvr-iot-common/src/main/java/com/cmvr/common/annotation" title="自定义注解"/>
<tree path="/cmvr-iot-common/src/main/java/com/cmvr/common/config" title="全局配置"/>
<tree path="/cmvr-iot-common/src/main/java/com/cmvr/common/constant" title="通用常量"/>
<tree path="/cmvr-iot-common/src/main/java/com/cmvr/common/core" title="核心控制"/>
<tree path="/cmvr-iot-common/src/main/java/com/cmvr/common/enums" title="通用枚举"/>
<tree path="/cmvr-iot-common/src/main/java/com/cmvr/common/exception" title="通用异常"/>
<tree path="/cmvr-iot-common/src/main/java/com/cmvr/common/filter" title="过滤器处理"/>
<tree path="/cmvr-iot-common/src/main/java/com/cmvr/common/utils" title="通用类处理"/>
<tree path="/cmvr-iot-common/src/main/java/com/cmvr/common/xss" title="自定义xss校验注解"/>
<tree path="/cmvr-iot-framework/src/main/java/com/cmvr/framework/aspectj" title="注解实现"/>
<tree path="/cmvr-iot-framework/src/main/java/com/cmvr/framework/config" title="系统配置"/>
<tree path="/cmvr-iot-framework/src/main/java/com/cmvr/framework/datasource" title="数据权限"/>
<tree path="/cmvr-iot-framework/src/main/java/com/cmvr/framework/interceptor" title="拦截器"/>
<tree path="/cmvr-iot-framework/src/main/java/com/cmvr/framework/manager" title="异步处理"/>
<tree path="/cmvr-iot-framework/src/main/java/com/cmvr/framework/security" title="权限控制"/>
<tree path="/cmvr-iot-framework/src/main/java/com/cmvr/framework/web" title="前端控制"/>
<tree path="/cmvr-iot-device" title="设备管理"/>
</trees>

50
Dockerfile Normal file
View File

@ -0,0 +1,50 @@
# ====================== 构建阶段 ======================
FROM maven:3.9.9-eclipse-temurin-8 AS builder
WORKDIR /app
# 缓存pom
COPY pom.xml .
COPY cmvr-iot-admin/pom.xml cmvr-iot-admin/
COPY cmvr-iot-framework/pom.xml cmvr-iot-framework/
COPY cmvr-iot-system/pom.xml cmvr-iot-system/
COPY cmvr-iot-quartz/pom.xml cmvr-iot-quartz/
COPY cmvr-iot-generator/pom.xml cmvr-iot-generator/
COPY cmvr-iot-common/pom.xml cmvr-iot-common/
COPY cmvr-iot-device/pom.xml cmvr-iot-device/
COPY cmvr-iot-test/pom.xml cmvr-iot-test/
COPY cmvr-iot-api/pom.xml cmvr-iot-api/
COPY cmvr-iot-vi/pom.xml cmvr-iot-vi/
COPY cmvr-iot-ti/pom.xml cmvr-iot-ti/
COPY cmvr-iot-evaluation/pom.xml cmvr-iot-evaluation/
COPY cmvr-iot-api/cmvr-iot-llm/pom.xml cmvr-iot-api/cmvr-iot-llm/
COPY cmvr-iot-api/cmvr-iot-edge/pom.xml cmvr-iot-api/cmvr-iot-edge/
COPY cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/pom.xml cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/
COPY cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/pom.xml cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/
RUN mvn dependency:go-offline -B --no-transfer-progress
COPY . .
RUN mvn clean package -DskipTests -pl cmvr-iot-admin -am --no-transfer-progress
# ====================== 运行阶段 ======================
FROM openjdk:8-jdk-alpine
WORKDIR /app
# -------------------------- 【唯一正确写法】 --------------------------
# 1. 先把所有jar复制进来
COPY --from=builder /app/cmvr-iot-admin/target/*.jar ./
# 2. 自动删除不能运行的小jar只保留可执行jar
RUN find . -name "*.jar" -type f -size -20000k -delete
# 3. 重命名为app.jar
RUN mv *.jar app.jar
ENTRYPOINT ["java", "-jar", \
"-Dspring.profiles.active=dev", \
"-Djava.security.egd=file:/dev/./urandom", \
"-XX:+UseG1GC", \
"-Xms512m", "-Xmx1024m", \
"app.jar"]

43
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,43 @@
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'mvn clean install -Dmaven.test.skip=true'
}
}
stage('Deploy') {
parallel {
stage('Deploy to DEV') {
steps {
sh './ry.sh start dev'
}
}
stage('Deploy to TEST') {
steps {
sh './ry.sh start test'
}
}
stage('Deploy to PROD') {
steps {
sh './ry.sh start prod'
}
}
}
}
}
post {
always {
archiveArtifacts artifacts: '**/*.jar', allowEmptyArchive: true
}
success {
echo 'Pipeline completed successfully.'
}
failure {
echo 'Pipeline failed.'
}
}
}

20
LICENSE Normal file
View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2018 RuoYi
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

273
README.md
View File

@ -1,92 +1,249 @@
# cmvr-iot # cmvr-iot
cmvr-iot 是一个基于 Java 8 和 Spring Boot 2.5 的多模块后端工程提供设备管理、边缘机器人控制、测试编排、巡检、TTS、AIMA、VI/TI 等业务能力。工程入口在 `cmvr-iot-admin`,其余模块按业务和基础能力拆分。
## 技术栈
## Getting started - Java 8
- Spring Boot 2.5.15
- Spring Security
- MyBatis Plus / MyBatis Plus Join
- MySQL / Redis
- Druid
- Quartz
- Knife4j / Swagger
- gRPC Java 1.58.0
- Protobuf / protoc-maven-plugin
- MinIO
To make it easy for you to get started with GitLab, here's a list of recommended next steps. ## 模块说明
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! | 模块 | 说明 |
| --- | --- |
| `cmvr-iot-admin` | Web 启动模块,包含 REST Controller、启动类和运行配置 |
| `cmvr-iot-framework` | Web、安全、配置、通用框架能力 |
| `cmvr-iot-common` | 公共工具、通用响应、基础常量和通用能力 |
| `cmvr-iot-system` | 系统管理、用户、角色、菜单、字典等基础业务 |
| `cmvr-iot-quartz` | 定时任务模块 |
| `cmvr-iot-generator` | 代码生成模块 |
| `cmvr-iot-device` | 设备领域模型与设备相关能力 |
| `cmvr-iot-test` | 测试任务、编排、执行实例等业务 |
| `cmvr-iot-vi` | VI 相关业务 |
| `cmvr-iot-ti` | TI 相关业务 |
| `cmvr-iot-evaluation` | 评测相关业务 |
| `cmvr-iot-inspection` | 巡检机器人、地图、任务、告警等业务 |
| `cmvr-iot-aima` | AIMA 相关业务 |
| `cmvr-iot-tts` | TTS 语音合成相关业务 |
| `cmvr-iot-api` | API 聚合模块 |
| `cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib` | gRPC proto 与生成代码模块 |
| `cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client` | 边缘设备 gRPC 客户端、设备控制服务和请求 VO |
## Add your files ## 目录结构
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files ```text
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: cmvr-iot
├── cmvr-iot-admin # Spring Boot 启动模块
``` ├── cmvr-iot-common # 公共模块
cd existing_repo ├── cmvr-iot-framework # 框架模块
git remote add origin http://192.168.1.100:18088/smart_bench/cmvr-iot.git ├── cmvr-iot-system # 系统管理模块
git branch -M main ├── cmvr-iot-device # 设备模块
git push -uf origin main ├── cmvr-iot-test # 测试业务模块
├── cmvr-iot-api
│ └── cmvr-iot-edge
│ ├── cmvr-iot-grpc-lib # proto 与 gRPC 生成代码
│ └── cmvr-iot-grpc-client # gRPC 客户端与边缘控制服务
├── sql # 增量 SQL
├── Dockerfile
├── Jenkinsfile
└── pom.xml # Maven 父工程
``` ```
## Integrate with your tools ## 环境要求
- [ ] [Set up project integrations](http://192.168.1.100:18088/smart_bench/cmvr-iot/-/settings/integrations) - JDK 1.8
- Maven 3.6+
- MySQL 5.7+/8.x
- Redis
- 可访问的 gRPC 机器人/边缘终端服务
- 可选MinIO、外部大模型/TTS/评测服务
## Collaborate with your team 注意:`application-*.yml` 中包含环境相关地址、账号和密钥配置。实际部署或本地开发时,应使用本机配置、环境变量或配置中心覆盖,不要直接复用生产/测试环境敏感配置。
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) ## 配置文件
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
## Test and Deploy 主配置文件位于:
Use the built-in continuous integration in GitLab. ```text
cmvr-iot-admin/src/main/resources/application.yml
```
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) 环境配置文件位于:
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
*** ```text
cmvr-iot-admin/src/main/resources/application-dev.yml
cmvr-iot-admin/src/main/resources/application-test.yml
cmvr-iot-admin/src/main/resources/application-prod.yml
```
# Editing this README 当前 `application.yml` 默认激活:
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template. ```yaml
spring:
profiles:
active: test
```
## Suggestions for a good README 如需切换环境,可以修改 `spring.profiles.active`,或启动时指定:
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## Name ```bash
Choose a self-explaining name for your project. java -jar cmvr-iot-admin-dev.jar --spring.profiles.active=dev
```
## Description ## 构建
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges 在项目根目录执行:
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals ```bash
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. mvn clean package -DskipTests
```
## Installation 只编译启动模块及其依赖:
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
## Usage ```bash
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. mvn -pl cmvr-iot-admin -am compile -DskipTests
```
## Support 只重新生成并编译 gRPC 代码:
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Roadmap ```bash
If you have ideas for releases in the future, it is a good idea to list them in the README. mvn -pl cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib -am compile -DskipTests
```
## Contributing ## 启动
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. 启动类:
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. ```text
cmvr-iot-admin/src/main/java/com/cmvr/CmvrIotApplication.java
```
## Authors and acknowledgment IDE 中直接运行 `CmvrIotApplication` 即可。
Show your appreciation to those who have contributed to the project.
## License 打包后运行:
For open source projects, say how it is licensed.
## Project status ```bash
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. java -jar cmvr-iot-admin/target/cmvr-iot-admin-dev.jar --spring.profiles.active=dev
```
默认开发端口以当前 profile 配置为准,例如 `application-dev.yml` 中为:
```yaml
server:
port: 13080
```
## 接口文档
项目集成 Knife4j / Swagger。服务启动后可访问
```text
http://localhost:13080/doc.html
```
如果端口或上下文路径被 profile 覆盖,请以实际配置为准。
## 数据库脚本
增量脚本位于:
```text
sql/
```
当前包含:
- `aima_module.sql`
- `inspection_module.sql`
- `tts_corpus_module.sql`
初始化数据库时,需要结合目标环境的基础库结构和增量脚本执行。
## gRPC 与边缘设备
边缘设备相关代码集中在:
```text
cmvr-iot-api/cmvr-iot-edge/
```
proto 文件位于:
```text
cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/proto/
```
gRPC 客户端服务位于:
```text
cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/
```
边缘控制器位于:
```text
cmvr-iot-admin/src/main/java/com/cmvr/web/controller/api/
```
新增或修改 proto 后,执行 Maven compile 会触发 `protoc-maven-plugin` 生成 Java 和 gRPC Stub 代码。业务代码应复用现有 gRPC 客户端管理工具获取 Stub避免在业务层重复创建底层 `ManagedChannel`
## 实时语音对讲
当前实时语音对讲链路为:
```text
浏览器 WebSocket Binary PCM <-> Java 后端 <-> gRPC 双向流 <-> 机器人终端
```
约定音频格式:
- PCM_S16LE
- 48000 Hz
- 单声道
- 16 bit
- 10 ms 一帧
- 960 bytes/帧
相关文件:
- WebSocket 控制器:`cmvr-iot-admin/src/main/java/com/cmvr/web/controller/api/WebRtcSignalingController.java`
- 业务会话管理:`cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/AudioService.java`
- gRPC 音频适配:`cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/adapter/RobotAudioGrpcAdapter.java`
- proto`cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/proto/cmvr/api/robot_audio.proto`
说明:历史 WebRTC 相关类可能仍保留在源码中,但当前浏览器音频传输链路使用 WebSocket 二进制 PCM。
## 开发约定
- Controller 层只做参数接收、基础校验和响应封装。
- POST 控制类接口优先使用单个 `@RequestBody VO` 承载完整请求参数。
- GET 查询类接口可以使用 query 参数绑定 VO。
- 不建议在同一个接口中同时声明通用 VO 和零散业务参数。
- gRPC 调用统一通过现有客户端管理类获取 Stub。
- proto 修改后必须重新编译并确认生成代码已更新。
- 不要提交本地日志、崩溃 dump、临时音频文件和包含真实密钥的配置。
## 常用命令
```bash
# 编译全部模块
mvn clean compile -DskipTests
# 编译启动模块及依赖
mvn -pl cmvr-iot-admin -am compile -DskipTests
# 打包
mvn clean package -DskipTests
# 运行指定 profile
java -jar cmvr-iot-admin/target/cmvr-iot-admin-dev.jar --spring.profiles.active=dev
```

126
cmvr-iot-admin/pom.xml Normal file
View File

@ -0,0 +1,126 @@
<?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"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cmvr-iot</artifactId>
<groupId>com.cmvr</groupId>
<version>3.8.9</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>cmvr-iot-admin</artifactId>
<description>
web服务入口
</description>
<dependencies>
<!-- spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency>
<!-- Mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 测试管理-->
<dependency>
<groupId>com.cmvr</groupId>
<artifactId>cmvr-iot-test</artifactId>
</dependency>
<!-- 核心模块-->
<dependency>
<groupId>com.cmvr</groupId>
<artifactId>cmvr-iot-framework</artifactId>
</dependency>
<!-- 定时任务-->
<dependency>
<groupId>com.cmvr</groupId>
<artifactId>cmvr-iot-quartz</artifactId>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.cmvr</groupId>
<artifactId>cmvr-iot-generator</artifactId>
</dependency>
<!-- 设备管理-->
<dependency>
<groupId>com.cmvr</groupId>
<artifactId>cmvr-iot-device</artifactId>
</dependency>
<!-- 语音交互-->
<dependency>
<groupId>com.cmvr</groupId>
<artifactId>cmvr-iot-vi</artifactId>
</dependency>
<!-- 触控交互-->
<dependency>
<groupId>com.cmvr</groupId>
<artifactId>cmvr-iot-ti</artifactId>
</dependency>
<!-- AI评估-->
<dependency>
<groupId>com.cmvr</groupId>
<artifactId>cmvr-iot-evaluation</artifactId>
</dependency>
<!-- 智能巡检-->
<dependency>
<groupId>com.cmvr</groupId>
<artifactId>cmvr-iot-inspection</artifactId>
</dependency>
<!-- 爱玛电动车测试-->
<dependency>
<groupId>com.cmvr</groupId>
<artifactId>cmvr-iot-aima</artifactId>
</dependency>
<!-- 智能座舱语音语料采集-->
<dependency>
<groupId>com.cmvr</groupId>
<artifactId>cmvr-iot-tts</artifactId>
</dependency>
</dependencies>
<properties>
<env>dev</env>
</properties>
<build>
<plugins>
<!-- Spring Boot Maven 插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.15</version>
<configuration>
<mainClass>com.cmvr.CmvrIotApplication</mainClass>
<fork>true</fork> <!-- 如果没有该配置, devtools 不会生效 -->
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<finalName>${project.artifactId}-${spring.profiles.active}</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,25 @@
package com.cmvr;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* 启动程序
*
* @author cmvr-iot
*/
@EnableScheduling
@MapperScan("com.cmvr.**.mapper")
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class CmvrIotApplication
{
public static void main(String[] args)
{
// System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(CmvrIotApplication.class, args);
System.out.println("招商车研物联网平台启动成功");
}
}

View File

@ -0,0 +1,18 @@
package com.cmvr;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* web容器中进行部署
*
* @author cmvr-iot
*/
public class CmvrIotServletInitializer extends SpringBootServletInitializer
{
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{
return application.sources(CmvrIotApplication.class);
}
}

View File

@ -0,0 +1,43 @@
package com.cmvr.web.controller;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.edge.client.service.EdgeHlcService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@Api(tags = "通用--测试")
@RestController
@RequestMapping("/common/test")
@RequiredArgsConstructor
public class TestController extends BaseController {
private final EdgeHlcService edgeHlcService;
@ApiOperation("图片标注")
@PostMapping("/mark")
public AjaxResult mark(
@RequestPart("image") MultipartFile image,
@RequestParam("x") Integer x,
@RequestParam("y") Integer y
) {
try {
File tempFile = File.createTempFile("upload_", "_" + image.getOriginalFilename());
image.transferTo(tempFile);
edgeHlcService.markPoint(tempFile,x,y);
} catch (IOException e) {
throw new RuntimeException(e);
}
return AjaxResult.ok();
}
}

View File

@ -0,0 +1,75 @@
package com.cmvr.web.controller.aima;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.aima.domain.AimaAlarm;
import com.cmvr.aima.service.IAimaAlarmService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
@RestController
@RequestMapping("/aima/alarm")
@Api(tags = "爱玛电动车--告警管理")
public class AimaAlarmController extends BaseController {
@Autowired
private IAimaAlarmService aimaAlarmService;
@ApiOperation("查询告警列表")
@PreAuthorize("@ss.hasPermi('aima:alarm:list')")
@GetMapping("/list")
public TableDataInfo list(AimaAlarm aimaAlarm) {
startPage();
List<AimaAlarm> list = aimaAlarmService.selectAimaAlarmList(aimaAlarm);
return getDataTable(list);
}
@ApiOperation("导出告警列表")
@PreAuthorize("@ss.hasPermi('aima:alarm:export')")
@Log(title = "告警管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AimaAlarm aimaAlarm) {
List<AimaAlarm> list = aimaAlarmService.selectAimaAlarmList(aimaAlarm);
ExcelUtil<AimaAlarm> util = new ExcelUtil<>(AimaAlarm.class);
util.exportExcel(response, list, "告警数据");
}
@ApiOperation("获取告警详细信息")
@PreAuthorize("@ss.hasPermi('aima:alarm:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id) {
return success(aimaAlarmService.selectAimaAlarmById(id));
}
@ApiOperation("新增告警")
@PreAuthorize("@ss.hasPermi('aima:alarm:add')")
@Log(title = "告警管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AimaAlarm aimaAlarm) {
return toAjax(aimaAlarmService.insertAimaAlarm(aimaAlarm));
}
@ApiOperation("修改告警")
@PreAuthorize("@ss.hasPermi('aima:alarm:edit')")
@Log(title = "告警管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AimaAlarm aimaAlarm) {
return toAjax(aimaAlarmService.updateAimaAlarm(aimaAlarm));
}
@ApiOperation("删除告警")
@PreAuthorize("@ss.hasPermi('aima:alarm:remove')")
@Log(title = "告警管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(aimaAlarmService.deleteAimaAlarmByIds(ids));
}
}

View File

@ -0,0 +1,113 @@
package com.cmvr.web.controller.aima;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.aima.domain.AimaPhone;
import com.cmvr.aima.service.IAimaPhoneService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
/**
* 爱玛手机管理Controller
*
* @author cmvr-iot
* @since 2026-06-22
*/
@RestController
@RequestMapping("/aima/phone")
@Api(tags = "爱玛电动车--手机管理")
public class AimaPhoneController extends BaseController
{
@Autowired
private IAimaPhoneService aimaPhoneService;
/**
* 查询爱玛手机管理列表
*/
@ApiOperation("查询爱玛手机管理列表")
@PreAuthorize("@ss.hasPermi('aima:phone:list')")
@GetMapping("/list")
public TableDataInfo list(AimaPhone aimaPhone)
{
startPage();
List<AimaPhone> list = aimaPhoneService.selectAimaPhoneList(aimaPhone);
return getDataTable(list);
}
/**
* 导出爱玛手机管理列表
*/
@ApiOperation("导出爱玛手机管理列表")
@PreAuthorize("@ss.hasPermi('aima:phone:export')")
@Log(title = "爱玛手机管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AimaPhone aimaPhone)
{
List<AimaPhone> list = aimaPhoneService.selectAimaPhoneList(aimaPhone);
ExcelUtil<AimaPhone> util = new ExcelUtil<>(AimaPhone.class);
util.exportExcel(response, list, "爱玛手机管理数据");
}
/**
* 获取爱玛手机管理详细信息
*/
@ApiOperation("获取爱玛手机管理详细信息")
@PreAuthorize("@ss.hasPermi('aima:phone:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id)
{
return success(aimaPhoneService.selectAimaPhoneById(id));
}
/**
* 新增爱玛手机管理
*/
@ApiOperation("新增爱玛手机管理")
@PreAuthorize("@ss.hasPermi('aima:phone:add')")
@Log(title = "爱玛手机管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AimaPhone aimaPhone)
{
return toAjax(aimaPhoneService.insertAimaPhone(aimaPhone));
}
/**
* 修改爱玛手机管理
*/
@ApiOperation("修改爱玛手机管理")
@PreAuthorize("@ss.hasPermi('aima:phone:edit')")
@Log(title = "爱玛手机管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AimaPhone aimaPhone)
{
return toAjax(aimaPhoneService.updateAimaPhone(aimaPhone));
}
/**
* 删除爱玛手机管理
*/
@ApiOperation("删除爱玛手机管理")
@PreAuthorize("@ss.hasPermi('aima:phone:remove')")
@Log(title = "爱玛手机管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
return toAjax(aimaPhoneService.deleteAimaPhoneByIds(ids));
}
}

View File

@ -0,0 +1,98 @@
package com.cmvr.web.controller.aima;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.aima.domain.AimaTask;
import com.cmvr.aima.domain.vo.AimaTaskVo;
import com.cmvr.aima.service.IAimaTaskService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
@RestController
@RequestMapping("/aima/task")
@Api(tags = "爱玛电动车--任务管理")
public class AimaTaskController extends BaseController {
@Autowired
private IAimaTaskService aimaTaskService;
@ApiOperation("查询任务列表")
@PreAuthorize("@ss.hasPermi('aima:task:list')")
@GetMapping("/list")
public TableDataInfo list(AimaTask aimaTask) {
startPage();
List<AimaTaskVo> list = aimaTaskService.selectAimaTaskVoList(aimaTask);
return getDataTable(list);
}
@ApiOperation("导出任务列表")
@PreAuthorize("@ss.hasPermi('aima:task:export')")
@Log(title = "任务管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AimaTask aimaTask) {
List<AimaTaskVo> list = aimaTaskService.selectAimaTaskVoList(aimaTask);
ExcelUtil<AimaTaskVo> util = new ExcelUtil<>(AimaTaskVo.class);
util.exportExcel(response, list, "任务数据");
}
@ApiOperation("获取任务详细信息")
@PreAuthorize("@ss.hasPermi('aima:task:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id) {
return success(aimaTaskService.selectAimaTaskById(id));
}
@ApiOperation("新增任务")
@PreAuthorize("@ss.hasPermi('aima:task:add')")
@Log(title = "任务管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AimaTask aimaTask) {
return toAjax(aimaTaskService.insertAimaTask(aimaTask));
}
@ApiOperation("修改任务")
@PreAuthorize("@ss.hasPermi('aima:task:edit')")
@Log(title = "任务管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AimaTask aimaTask) {
return toAjax(aimaTaskService.updateAimaTask(aimaTask));
}
@ApiOperation("删除任务")
@PreAuthorize("@ss.hasPermi('aima:task:remove')")
@Log(title = "任务管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(aimaTaskService.deleteAimaTaskByIds(ids));
}
/**
* 绑定测试用例到任务
*/
@ApiOperation("绑定测试用例")
@PreAuthorize("@ss.hasPermi('aima:task:edit')")
@Log(title = "任务管理", businessType = BusinessType.UPDATE)
@PostMapping("/bindTestCases/{taskId}")
public AjaxResult bindTestCases(@PathVariable("taskId") String taskId, @RequestBody List<String> testCaseIds) {
aimaTaskService.bindTestCases(taskId, testCaseIds);
return success();
}
/**
* 获取任务的测试用例列表
*/
@ApiOperation("获取任务测试用例")
@PreAuthorize("@ss.hasPermi('aima:task:query')")
@GetMapping("/testCases/{taskId}")
public AjaxResult getTestCases(@PathVariable String taskId) {
return success(aimaTaskService.getTestCaseIds(taskId));
}
}

View File

@ -0,0 +1,121 @@
package com.cmvr.web.controller.aima;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.aima.domain.AimaTaskInstance;
import com.cmvr.aima.domain.dto.AimaTaskInstanceQuery;
import com.cmvr.aima.domain.vo.AimaTaskInstanceVo;
import com.cmvr.aima.service.IAimaTaskInstanceService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
@RestController
@RequestMapping("/aima/taskinstance")
@Api(tags = "爱玛电动车--任务执行实例")
public class AimaTaskInstanceController extends BaseController {
@Autowired
private IAimaTaskInstanceService aimaTaskInstanceService;
@ApiOperation("查询任务实例列表")
@PreAuthorize("@ss.hasPermi('aima:taskinstance:list')")
@GetMapping("/list")
public TableDataInfo list(AimaTaskInstanceQuery query) {
startPage();
List<AimaTaskInstanceVo> list = aimaTaskInstanceService.selectAimaTaskInstanceVoList(query);
return getDataTable(list);
}
@ApiOperation("导出任务实例列表")
@PreAuthorize("@ss.hasPermi('aima:taskinstance:export')")
@Log(title = "任务执行实例", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AimaTaskInstanceQuery query) {
List<AimaTaskInstanceVo> list = aimaTaskInstanceService.selectAimaTaskInstanceVoList(query);
ExcelUtil<AimaTaskInstanceVo> util = new ExcelUtil<>(AimaTaskInstanceVo.class);
util.exportExcel(response, list, "任务实例数据");
}
@ApiOperation("获取任务实例详细信息")
@PreAuthorize("@ss.hasPermi('aima:taskinstance:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id) {
return success(aimaTaskInstanceService.selectAimaTaskInstanceById(id));
}
@ApiOperation("新增任务实例")
@PreAuthorize("@ss.hasPermi('aima:taskinstance:add')")
@Log(title = "任务执行实例", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AimaTaskInstance aimaTaskInstance) {
return toAjax(aimaTaskInstanceService.insertAimaTaskInstance(aimaTaskInstance));
}
@ApiOperation("修改任务实例")
@PreAuthorize("@ss.hasPermi('aima:taskinstance:edit')")
@Log(title = "任务执行实例", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AimaTaskInstance aimaTaskInstance) {
return toAjax(aimaTaskInstanceService.updateAimaTaskInstance(aimaTaskInstance));
}
@ApiOperation("删除任务实例")
@PreAuthorize("@ss.hasPermi('aima:taskinstance:remove')")
@Log(title = "任务执行实例", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(aimaTaskInstanceService.deleteAimaTaskInstanceByIds(ids));
}
/**
* 开始执行任务实例
*/
@ApiOperation("开始执行任务实例")
@PreAuthorize("@ss.hasPermi('aima:taskinstance:edit')")
@Log(title = "任务执行实例", businessType = BusinessType.UPDATE)
@PutMapping("/start/{id}")
public AjaxResult start(@PathVariable("id") String id) {
return toAjax(aimaTaskInstanceService.startInstance(id));
}
/**
* 暂停任务实例
*/
@ApiOperation("暂停任务实例")
@PreAuthorize("@ss.hasPermi('aima:taskinstance:edit')")
@Log(title = "任务执行实例", businessType = BusinessType.UPDATE)
@PutMapping("/pause/{id}")
public AjaxResult pause(@PathVariable("id") String id) {
return toAjax(aimaTaskInstanceService.pauseInstance(id));
}
/**
* 终止任务实例
*/
@ApiOperation("终止任务实例")
@PreAuthorize("@ss.hasPermi('aima:taskinstance:edit')")
@Log(title = "任务执行实例", businessType = BusinessType.UPDATE)
@PutMapping("/stop/{id}")
public AjaxResult stop(@PathVariable("id") String id) {
return toAjax(aimaTaskInstanceService.stopInstance(id));
}
/**
* 恢复任务实例
*/
@ApiOperation("恢复任务实例")
@PreAuthorize("@ss.hasPermi('aima:taskinstance:edit')")
@Log(title = "任务执行实例", businessType = BusinessType.UPDATE)
@PutMapping("/resume/{id}")
public AjaxResult resume(@PathVariable("id") String id) {
return toAjax(aimaTaskInstanceService.resumeInstance(id));
}
}

View File

@ -0,0 +1,76 @@
package com.cmvr.web.controller.aima;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.aima.domain.AimaTestCase;
import com.cmvr.aima.domain.vo.AimaTestCaseVo;
import com.cmvr.aima.service.IAimaTestCaseService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
@RestController
@RequestMapping("/aima/testcase")
@Api(tags = "爱玛电动车--测试用例管理")
public class AimaTestCaseController extends BaseController {
@Autowired
private IAimaTestCaseService aimaTestCaseService;
@ApiOperation("查询测试用例列表")
@PreAuthorize("@ss.hasPermi('aima:testcase:list')")
@GetMapping("/list")
public TableDataInfo list(AimaTestCase aimaTestCase) {
startPage();
List<AimaTestCaseVo> list = aimaTestCaseService.selectAimaTestCaseVoList(aimaTestCase);
return getDataTable(list);
}
@ApiOperation("导出测试用例列表")
@PreAuthorize("@ss.hasPermi('aima:testcase:export')")
@Log(title = "测试用例管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AimaTestCase aimaTestCase) {
List<AimaTestCaseVo> list = aimaTestCaseService.selectAimaTestCaseVoList(aimaTestCase);
ExcelUtil<AimaTestCaseVo> util = new ExcelUtil<>(AimaTestCaseVo.class);
util.exportExcel(response, list, "测试用例数据");
}
@ApiOperation("获取测试用例详细信息")
@PreAuthorize("@ss.hasPermi('aima:testcase:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id) {
return success(aimaTestCaseService.selectAimaTestCaseById(id));
}
@ApiOperation("新增测试用例")
@PreAuthorize("@ss.hasPermi('aima:testcase:add')")
@Log(title = "测试用例管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AimaTestCase aimaTestCase) {
return toAjax(aimaTestCaseService.insertAimaTestCase(aimaTestCase));
}
@ApiOperation("修改测试用例")
@PreAuthorize("@ss.hasPermi('aima:testcase:edit')")
@Log(title = "测试用例管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AimaTestCase aimaTestCase) {
return toAjax(aimaTestCaseService.updateAimaTestCase(aimaTestCase));
}
@ApiOperation("删除测试用例")
@PreAuthorize("@ss.hasPermi('aima:testcase:remove')")
@Log(title = "测试用例管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(aimaTestCaseService.deleteAimaTestCaseByIds(ids));
}
}

View File

@ -0,0 +1,75 @@
package com.cmvr.web.controller.aima;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.aima.domain.AimaTestLog;
import com.cmvr.aima.service.IAimaTestLogService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
@RestController
@RequestMapping("/aima/testlog")
@Api(tags = "爱玛电动车--测试日志管理")
public class AimaTestLogController extends BaseController {
@Autowired
private IAimaTestLogService aimaTestLogService;
@ApiOperation("查询测试日志列表")
@PreAuthorize("@ss.hasPermi('aima:testlog:list')")
@GetMapping("/list")
public TableDataInfo list(AimaTestLog aimaTestLog) {
startPage();
List<AimaTestLog> list = aimaTestLogService.selectAimaTestLogList(aimaTestLog);
return getDataTable(list);
}
@ApiOperation("导出测试日志列表")
@PreAuthorize("@ss.hasPermi('aima:testlog:export')")
@Log(title = "测试日志管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AimaTestLog aimaTestLog) {
List<AimaTestLog> list = aimaTestLogService.selectAimaTestLogList(aimaTestLog);
ExcelUtil<AimaTestLog> util = new ExcelUtil<>(AimaTestLog.class);
util.exportExcel(response, list, "测试日志数据");
}
@ApiOperation("获取测试日志详细信息")
@PreAuthorize("@ss.hasPermi('aima:testlog:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id) {
return success(aimaTestLogService.selectAimaTestLogById(id));
}
@ApiOperation("新增测试日志")
@PreAuthorize("@ss.hasPermi('aima:testlog:add')")
@Log(title = "测试日志管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AimaTestLog aimaTestLog) {
return toAjax(aimaTestLogService.insertAimaTestLog(aimaTestLog));
}
@ApiOperation("修改测试日志")
@PreAuthorize("@ss.hasPermi('aima:testlog:edit')")
@Log(title = "测试日志管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AimaTestLog aimaTestLog) {
return toAjax(aimaTestLogService.updateAimaTestLog(aimaTestLog));
}
@ApiOperation("删除测试日志")
@PreAuthorize("@ss.hasPermi('aima:testlog:remove')")
@Log(title = "测试日志管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(aimaTestLogService.deleteAimaTestLogByIds(ids));
}
}

View File

@ -0,0 +1,75 @@
package com.cmvr.web.controller.aima;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.aima.domain.AimaVehicle;
import com.cmvr.aima.service.IAimaVehicleService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
@RestController
@RequestMapping("/aima/vehicle")
@Api(tags = "爱玛电动车--车辆管理")
public class AimaVehicleController extends BaseController {
@Autowired
private IAimaVehicleService aimaVehicleService;
@ApiOperation("查询车辆列表")
@PreAuthorize("@ss.hasPermi('aima:vehicle:list')")
@GetMapping("/list")
public TableDataInfo list(AimaVehicle aimaVehicle) {
startPage();
List<AimaVehicle> list = aimaVehicleService.selectAimaVehicleList(aimaVehicle);
return getDataTable(list);
}
@ApiOperation("导出车辆列表")
@PreAuthorize("@ss.hasPermi('aima:vehicle:export')")
@Log(title = "车辆管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, AimaVehicle aimaVehicle) {
List<AimaVehicle> list = aimaVehicleService.selectAimaVehicleList(aimaVehicle);
ExcelUtil<AimaVehicle> util = new ExcelUtil<>(AimaVehicle.class);
util.exportExcel(response, list, "车辆数据");
}
@ApiOperation("获取车辆详细信息")
@PreAuthorize("@ss.hasPermi('aima:vehicle:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id) {
return success(aimaVehicleService.selectAimaVehicleById(id));
}
@ApiOperation("新增车辆")
@PreAuthorize("@ss.hasPermi('aima:vehicle:add')")
@Log(title = "车辆管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AimaVehicle aimaVehicle) {
return toAjax(aimaVehicleService.insertAimaVehicle(aimaVehicle));
}
@ApiOperation("修改车辆")
@PreAuthorize("@ss.hasPermi('aima:vehicle:edit')")
@Log(title = "车辆管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody AimaVehicle aimaVehicle) {
return toAjax(aimaVehicleService.updateAimaVehicle(aimaVehicle));
}
@ApiOperation("删除车辆")
@PreAuthorize("@ss.hasPermi('aima:vehicle:remove')")
@Log(title = "车辆管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(aimaVehicleService.deleteAimaVehicleByIds(ids));
}
}

View File

@ -0,0 +1,40 @@
package com.cmvr.web.controller.api;
import com.cmvr.device.domain.DeDeviceRegistration;
import com.cmvr.device.service.IDeDeviceRegistrationService;
import com.cmvr.edge.client.service.EdgeSystemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "边缘--设备信息获取")
@RestController
@RequestMapping("/api/deviceList")
@RequiredArgsConstructor
public class DeviceListController {
private final EdgeSystemService systemService;
private final IDeDeviceRegistrationService registrationService;
@PreAuthorize("@ss.hasPermi('device:profile:list')")
@GetMapping("/addList")
@ApiOperation("同步设备信息列表")
public int addDeviceList(@RequestParam String terminalId){
List<DeDeviceRegistration> list = systemService.deviceList(terminalId);
return registrationService.addDeviceList(list);
}
}

View File

@ -0,0 +1,315 @@
package com.cmvr.web.controller.api;
import cmvr.msgs.Agv;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.edge.client.model.EdgeCommonVO;
import com.cmvr.edge.client.model.agv.EdgeAgvMapNameVO;
import com.cmvr.edge.client.model.agv.EdgeAgvNavigateToPoseVO;
import com.cmvr.edge.client.model.agv.EdgeAgvNavigateToStationVO;
import com.cmvr.edge.client.model.agv.EdgeAgvStartMappingVO;
import com.cmvr.edge.client.model.agv.EdgeAgvUploadMapVO;
import com.cmvr.edge.client.model.agv.EdgeAgvVelocityVO;
import com.cmvr.edge.client.service.EdgeAgvService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 边缘系统 AGV 控制器
*
* <p>接口入参约定
* GET 查询类接口使用 query 参数绑定 VOPOST 控制类接口只接收一个 JSON 请求体 VO
* 避免一个接口同时出现通用 VO 和零散业务参数保证前端调用Swagger 文档和后端绑定规则一致</p>
*
* @author cmvr-iot
* @since 2026-07-02
*/
@Api(tags = "边缘--AGV")
@RestController
@RequestMapping("/api/agv")
@RequiredArgsConstructor
public class EdgeAgvController {
private final EdgeAgvService edgeAgvService;
/**
* 获取 AGV 运行时状态
*/
@ApiOperation("获取AGV运行时状态")
@GetMapping("/getRuntimeState")
public AjaxResult getRuntimeState(@Validated EdgeCommonVO vo) {
Agv.AgvRuntimeState state = edgeAgvService.getRuntimeState(vo);
return AjaxResult.ok(toRuntimeStateMap(state));
}
/**
* 获取 AGV 当前导航状态
*/
@ApiOperation("获取导航状态")
@GetMapping("/getNavigationStatus")
public AjaxResult getNavigationStatus(@Validated EdgeCommonVO vo) {
Agv.AgvNavigationStatus status = edgeAgvService.getNavigationStatus(vo);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("state", status.getState());
resultMap.put("type", status.getType());
resultMap.put("progress", status.getProgress());
resultMap.put("message", status.getMessage());
return AjaxResult.ok(resultMap);
}
/**
* AGV 紧急停止
*/
@ApiOperation("紧急停止")
@PostMapping("/emergencyStop")
public AjaxResult emergencyStop(@RequestBody @Validated EdgeCommonVO vo) {
edgeAgvService.emergencyStop(vo);
return AjaxResult.ok();
}
/**
* 清除 AGV 故障
*/
@ApiOperation("清除故障")
@PostMapping("/clearFault")
public AjaxResult clearFault(@RequestBody @Validated EdgeCommonVO vo) {
edgeAgvService.clearFault(vo);
return AjaxResult.ok();
}
/**
* 导航到指定坐标
*/
@ApiOperation("导航到指定位置")
@PostMapping("/navigateToPose")
public AjaxResult navigateToPose(@RequestBody @Validated EdgeAgvNavigateToPoseVO vo) {
Agv.AgvPose2d pose = Agv.AgvPose2d.newBuilder()
.setX(vo.getX())
.setY(vo.getY())
.setTheta(vo.getTheta())
.build();
edgeAgvService.navigateToPose(vo, pose);
return AjaxResult.ok();
}
/**
* 导航到指定站点
*/
@ApiOperation("导航到站点")
@PostMapping("/navigateToStation")
public AjaxResult navigateToStation(@RequestBody @Validated EdgeAgvNavigateToStationVO vo) {
edgeAgvService.navigateToStation(vo, vo.getStationId());
return AjaxResult.ok();
}
/**
* 暂停当前导航任务
*/
@ApiOperation("暂停导航")
@PostMapping("/pauseNavigation")
public AjaxResult pauseNavigation(@RequestBody @Validated EdgeCommonVO vo) {
edgeAgvService.pauseNavigation(vo);
return AjaxResult.ok();
}
/**
* 恢复当前导航任务
*/
@ApiOperation("恢复导航")
@PostMapping("/resumeNavigation")
public AjaxResult resumeNavigation(@RequestBody @Validated EdgeCommonVO vo) {
edgeAgvService.resumeNavigation(vo);
return AjaxResult.ok();
}
/**
* 取消当前导航任务
*/
@ApiOperation("取消导航")
@PostMapping("/cancelNavigation")
public AjaxResult cancelNavigation(@RequestBody @Validated EdgeCommonVO vo) {
edgeAgvService.cancelNavigation(vo);
return AjaxResult.ok();
}
/**
* 设置 AGV 速度
*/
@ApiOperation("设置速度")
@PostMapping("/setVelocity")
public AjaxResult setVelocity(@RequestBody @Validated EdgeAgvVelocityVO vo) {
Agv.AgvVelocity velocity = Agv.AgvVelocity.newBuilder()
.setVx(vo.getVx())
.setVy(vo.getVy())
.setWz(vo.getWz())
.build();
edgeAgvService.setVelocity(vo, velocity);
return AjaxResult.ok();
}
/**
* 停止速度控制
*/
@ApiOperation("停止速度控制")
@PostMapping("/stopVelocityControl")
public AjaxResult stopVelocityControl(@RequestBody @Validated EdgeCommonVO vo) {
edgeAgvService.stopVelocityControl(vo);
return AjaxResult.ok();
}
/**
* 查询机器人本地所有地图
*/
@ApiOperation("列出所有地图")
@GetMapping("/listMaps")
public AjaxResult listMaps(@Validated EdgeCommonVO vo) {
List<String> maps = edgeAgvService.listMaps(vo);
return AjaxResult.ok(maps);
}
/**
* 查询机器人本地所有站点
*/
@ApiOperation("列出所有站点")
@GetMapping("/listStations")
public AjaxResult listStations(@Validated EdgeCommonVO vo) {
List<Agv.AgvStation> stations = edgeAgvService.listStations(vo);
List<Map<String, Object>> stationList = new ArrayList<>();
for (Agv.AgvStation station : stations) {
stationList.add(toStationMap(station));
}
return AjaxResult.ok(stationList);
}
/**
* 切换机器人当前地图
*/
@ApiOperation("切换地图")
@PostMapping("/switchMap")
public AjaxResult switchMap(@RequestBody @Validated EdgeAgvMapNameVO vo) {
edgeAgvService.switchMap(vo, vo.getMapName());
return AjaxResult.ok();
}
/**
* 上传地图内容到机器人
*/
@ApiOperation("上传地图")
@PostMapping("/uploadMap")
public AjaxResult uploadMap(@RequestBody @Validated EdgeAgvUploadMapVO vo) {
edgeAgvService.uploadMap(vo, vo.getMapName(), vo.getContent());
return AjaxResult.ok();
}
/**
* 下载指定地图内容
*/
@ApiOperation("下载地图")
@GetMapping("/downloadMap")
public AjaxResult downloadMap(@Validated EdgeAgvMapNameVO vo) {
String content = edgeAgvService.downloadMap(vo, vo.getMapName());
return AjaxResult.ok(content);
}
/**
* 开始建图
*/
@ApiOperation("开始建图")
@PostMapping("/startMapping")
public AjaxResult startMapping(@RequestBody @Validated EdgeAgvStartMappingVO vo) {
Agv.AgvMapDimension mapDimension = Agv.AgvMapDimension.forNumber(vo.getDimension());
if (mapDimension == null) {
return AjaxResult.error("建图维度不合法允许值0=未指定1=2D2=3D3=2D+3D");
}
String sessionId = edgeAgvService.startMapping(vo, mapDimension, vo.getMapName(), vo.isRealTime());
Map<String, Object> result = new HashMap<>();
result.put("sessionId", sessionId);
return AjaxResult.ok(result);
}
/**
* 停止建图
*/
@ApiOperation("停止建图")
@PostMapping("/stopMapping")
public AjaxResult stopMapping(@RequestBody @Validated EdgeCommonVO vo) {
edgeAgvService.stopMapping(vo);
return AjaxResult.ok();
}
/**
* protobuf 运行时状态转换为前端友好的 Map避免直接暴露 protobuf 对象结构
*/
private Map<String, Object> toRuntimeStateMap(Agv.AgvRuntimeState state) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("timestamp", state.getTimestamp());
resultMap.put("mode", state.getMode());
resultMap.put("connected", state.getConnected());
resultMap.put("localized", state.getLocalized());
resultMap.put("moving", state.getMoving());
resultMap.put("fault", state.getFault());
resultMap.put("emergencyStopped", state.getEmergencyStopped());
if (state.hasPose()) {
resultMap.put("pose", toPoseMap(state.getPose()));
}
if (state.hasVelocity()) {
Map<String, Object> velocityMap = new HashMap<>();
velocityMap.put("vx", state.getVelocity().getVx());
velocityMap.put("vy", state.getVelocity().getVy());
velocityMap.put("wz", state.getVelocity().getWz());
resultMap.put("velocity", velocityMap);
}
if (state.hasBattery()) {
Map<String, Object> batteryMap = new HashMap<>();
batteryMap.put("percentage", state.getBattery().getPercentage());
batteryMap.put("voltage", state.getBattery().getVoltage());
batteryMap.put("current", state.getBattery().getCurrent());
batteryMap.put("temperature", state.getBattery().getTemperature());
batteryMap.put("charging", state.getBattery().getCharging());
resultMap.put("battery", batteryMap);
}
resultMap.put("currentMap", state.getCurrentMap());
resultMap.put("currentStation", state.getCurrentStation());
resultMap.put("lastError", state.getLastError());
return resultMap;
}
/**
* protobuf 站点对象转换为普通 Map
*/
private Map<String, Object> toStationMap(Agv.AgvStation station) {
Map<String, Object> stationMap = new HashMap<>();
stationMap.put("id", station.getId());
stationMap.put("type", station.getType());
stationMap.put("description", station.getDescription());
if (station.hasPose()) {
stationMap.put("pose", toPoseMap(station.getPose()));
}
return stationMap;
}
/**
* protobuf 二维位姿转换为普通 Map
*/
private Map<String, Object> toPoseMap(Agv.AgvPose2d pose) {
Map<String, Object> poseMap = new HashMap<>();
poseMap.put("x", pose.getX());
poseMap.put("y", pose.getY());
poseMap.put("theta", pose.getTheta());
return poseMap;
}
}

View File

@ -0,0 +1,232 @@
package com.cmvr.web.controller.api;
import cmvr.api.ArmCommand;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.edge.client.model.EdgeCommonVO;
import com.cmvr.edge.client.model.arm.*;
import com.cmvr.edge.client.service.EdgeArmService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 边缘系统机械臂控制器
*
* @author cmvr-iot
* @since 2026-07-01
*/
@Api(tags = "边缘--机械臂")
@RestController
@RequestMapping("/api/arm")
@RequiredArgsConstructor
public class EdgeArmController {
private final EdgeArmService edgeArmService;
@ApiOperation("关闭力矩")
@GetMapping("/torqueOff")
public AjaxResult torqueOff(EdgeCommonVO vo) {
edgeArmService.torqueOff(vo);
return AjaxResult.ok();
}
@ApiOperation("开启力矩")
@GetMapping("/torqueOn")
public AjaxResult torqueOn(EdgeCommonVO vo) {
edgeArmService.torqueOn(vo);
return AjaxResult.ok();
}
/**
* 清除机械臂故障状态
*/
@ApiOperation("清除故障")
@GetMapping("/clearFault")
public AjaxResult clearFault(EdgeCommonVO vo) {
edgeArmService.clearFault(vo);
return AjaxResult.ok();
}
@ApiOperation("关节空间运动")
@PostMapping("/moveJ")
public AjaxResult moveJ(@RequestBody EdgeArmMoveJVO moveJVO) {
edgeArmService.moveJ(
moveJVO,
moveJVO.getTarget(),
moveJVO.getVelocity(),
moveJVO.getAcceleration(),
moveJVO.getBlendRadius(),
moveJVO.getJointVelocityLimits(),
moveJVO.getAsynchronous()
);
return AjaxResult.ok();
}
@ApiOperation("笛卡尔空间直线运动")
@PostMapping("/moveL")
public AjaxResult moveL(@RequestBody EdgeArmMoveLVO moveLVO) {
edgeArmService.moveL(
moveLVO,
moveLVO.getX(),
moveLVO.getY(),
moveLVO.getZ(),
moveLVO.getRx(),
moveLVO.getRy(),
moveLVO.getRz(),
moveLVO.getFrame(),
moveLVO.getVelocity(),
moveLVO.getAcceleration(),
moveLVO.getBlendRadius()
);
return AjaxResult.ok();
}
@ApiOperation("关节速度控制")
@PostMapping("/speedJ")
public AjaxResult speedJ(@RequestBody EdgeArmSpeedJVO speedJVO) {
edgeArmService.speedJ(
speedJVO,
speedJVO.getVelocities(),
speedJVO.getAcceleration(),
speedJVO.getDuration()
);
return AjaxResult.ok();
}
@ApiOperation("笛卡尔速度控制")
@PostMapping("/speedL")
public AjaxResult speedL(@RequestBody EdgeArmSpeedLVO speedLVO) {
edgeArmService.speedL(
speedLVO,
speedLVO.getVx(),
speedLVO.getVy(),
speedLVO.getVz(),
speedLVO.getWx(),
speedLVO.getWy(),
speedLVO.getWz(),
speedLVO.getFrame(),
speedLVO.getAcceleration(),
speedLVO.getDuration()
);
return AjaxResult.ok();
}
@ApiOperation("伺服关节控制")
@PostMapping("/servoJ")
public AjaxResult servoJ(@RequestBody EdgeArmServoJVO servoJVO) {
edgeArmService.servoJ(servoJVO, servoJVO.getTarget());
return AjaxResult.ok();
}
@ApiOperation("停止运动")
@GetMapping("/stopMotion")
public AjaxResult stopMotion(EdgeCommonVO vo) {
edgeArmService.stopMotion(vo);
return AjaxResult.ok();
}
@ApiOperation("获取关节状态")
@GetMapping("/getJointState")
public AjaxResult getJointState(EdgeCommonVO vo) {
ArmCommand.JointResponse result = edgeArmService.getJointState(vo);
ArmCommand.JointState state = result.getState();
// 转换为VO
EdgeArmJointStateVO jointStateVO = new EdgeArmJointStateVO();
jointStateVO.setName(state.getNameList());
jointStateVO.setPosition(state.getPositionList());
jointStateVO.setVelocity(state.getVelocityList());
jointStateVO.setEffort(state.getEffortList());
jointStateVO.setTimestamp(state.getTimestamp());
return AjaxResult.ok(jointStateVO);
}
@ApiOperation("获取末端位姿")
@GetMapping("/getPose")
public AjaxResult getPose(@Validated EdgeArmPoseQueryVO vo) {
ArmCommand.GetPose.Response result = edgeArmService.getPose(vo, vo.getBaseLink(), vo.getEeLink());
ArmCommand.CartesianPose pose = result.getPose();
// 转换为VO
EdgeArmCartesianPoseVO poseVO = new EdgeArmCartesianPoseVO();
poseVO.setX(pose.getX());
poseVO.setY(pose.getY());
poseVO.setZ(pose.getZ());
poseVO.setRx(pose.getRx());
poseVO.setRy(pose.getRy());
poseVO.setRz(pose.getRz());
return AjaxResult.ok(poseVO);
}
@ApiOperation("标定零点")
@GetMapping("/calibrateZeroQ")
public AjaxResult calibrateZeroQ(@Validated EdgeArmCalibrateZeroQVO vo) {
edgeArmService.calibrateZeroQ(vo, vo.getJointName());
return AjaxResult.ok();
}
@ApiOperation("获取位姿矩阵")
@GetMapping("/getPoseMatrix")
public AjaxResult getPoseMatrix(@Validated EdgeArmPoseQueryVO vo) {
ArmCommand.GetPoseMatrix.Response result = edgeArmService.getPoseMatrix(vo, vo.getBaseLink(), vo.getEeLink());
// 将TransformMatrix4x4转换为Map
ArmCommand.TransformMatrix4x4 matrix = result.getMatrix();
java.util.Map<String, Object> matrixMap = new java.util.HashMap<>();
matrixMap.put("m00", matrix.getM00());
matrixMap.put("m01", matrix.getM01());
matrixMap.put("m02", matrix.getM02());
matrixMap.put("m03", matrix.getM03());
matrixMap.put("m10", matrix.getM10());
matrixMap.put("m11", matrix.getM11());
matrixMap.put("m12", matrix.getM12());
matrixMap.put("m13", matrix.getM13());
matrixMap.put("m20", matrix.getM20());
matrixMap.put("m21", matrix.getM21());
matrixMap.put("m22", matrix.getM22());
matrixMap.put("m23", matrix.getM23());
matrixMap.put("m30", matrix.getM30());
matrixMap.put("m31", matrix.getM31());
matrixMap.put("m32", matrix.getM32());
matrixMap.put("m33", matrix.getM33());
return AjaxResult.ok(matrixMap);
}
@ApiOperation("计算正向运动学")
@PostMapping("/computeForwardKinematics")
public AjaxResult computeForwardKinematics(@RequestBody EdgeArmForwardKinematicsVO fkVO) {
ArmCommand.ComputeForwardKinematics.Response result = edgeArmService.computeForwardKinematics(
fkVO,
fkVO.getJoints(),
fkVO.getBaseLink(),
fkVO.getEeLink()
);
// 将TransformMatrix4x4转换为Map
ArmCommand.TransformMatrix4x4 matrix = result.getMatrix();
java.util.Map<String, Object> matrixMap = new java.util.HashMap<>();
matrixMap.put("m00", matrix.getM00());
matrixMap.put("m01", matrix.getM01());
matrixMap.put("m02", matrix.getM02());
matrixMap.put("m03", matrix.getM03());
matrixMap.put("m10", matrix.getM10());
matrixMap.put("m11", matrix.getM11());
matrixMap.put("m12", matrix.getM12());
matrixMap.put("m13", matrix.getM13());
matrixMap.put("m20", matrix.getM20());
matrixMap.put("m21", matrix.getM21());
matrixMap.put("m22", matrix.getM22());
matrixMap.put("m23", matrix.getM23());
matrixMap.put("m30", matrix.getM30());
matrixMap.put("m31", matrix.getM31());
matrixMap.put("m32", matrix.getM32());
matrixMap.put("m33", matrix.getM33());
return AjaxResult.ok(matrixMap);
}
}

View File

@ -0,0 +1,35 @@
package com.cmvr.web.controller.api;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.edge.client.model.EdgeCommonVO;
import com.cmvr.edge.client.model.biohead.EdgeFacialExpressionVO;
import com.cmvr.edge.client.service.EdgeBioHeadService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "边缘--机器人头部")
@RestController
@RequestMapping("/api/biohead")
@RequiredArgsConstructor
public class EdgeBioHeadController extends BaseController {
private final EdgeBioHeadService edgeBioHeadService;
@ApiOperation("设置面部表情")
@PostMapping("/expression")
public AjaxResult expression(@RequestBody EdgeFacialExpressionVO facialExpressionVo) {
return success(edgeBioHeadService.setExpression(facialExpressionVo));
}
@ApiOperation("紧急停止")
@PostMapping("/stop")
public AjaxResult emergencyStop(@RequestBody EdgeCommonVO edgeCommonVO) {
return success(edgeBioHeadService.emergencyStop(edgeCommonVO));
}
}

View File

@ -0,0 +1,64 @@
package com.cmvr.web.controller.api;
import com.alibaba.fastjson2.JSON;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.edge.client.model.EdgeCommonVO;
import com.cmvr.edge.client.service.EdgeCameraService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "边缘--相机")
@RestController
@RequestMapping("/api/edge/camera")
@RequiredArgsConstructor
public class EdgeCameraController extends BaseController {
private final EdgeCameraService edgeCameraService;
@ApiOperation("获取相机状态")
@GetMapping("/status")
public AjaxResult status(EdgeCommonVO edgeCommonVO) {
return success(JSON.toJSONString(edgeCameraService.status(edgeCommonVO)));
}
@ApiOperation("开启相机")
@GetMapping("/start")
public AjaxResult start(EdgeCommonVO edgeCommonVO) {
return success(edgeCameraService.start(edgeCommonVO));
}
@ApiOperation("关闭相机")
@GetMapping("/stop")
public AjaxResult stop(EdgeCommonVO edgeCommonVO) {
return success(edgeCameraService.stop(edgeCommonVO));
}
@ApiOperation("获取图片")
@GetMapping("/getRGBImage")
public AjaxResult getRGBImage(EdgeCommonVO edgeCommonVO) {
return success(edgeCameraService.getRGBImage(edgeCommonVO));
}
@ApiOperation("开始录制视频")
@GetMapping("/startRecording")
public AjaxResult startRecording(EdgeCommonVO edgeCommonVO) {
return success(edgeCameraService.startRecording(edgeCommonVO));
}
@ApiOperation("停止录制视频")
@GetMapping("/stopRecording")
public AjaxResult stopRecording(EdgeCommonVO edgeCommonVO) {
return success(edgeCameraService.stopRecording(edgeCommonVO));
}
@ApiOperation("获取图片和视频")
@GetMapping("/getRGBDImages")
public AjaxResult getRGBDImages(EdgeCommonVO edgeCommonVO) {
return success(edgeCameraService.getRGBDImages(edgeCommonVO));
}
}

View File

@ -0,0 +1,24 @@
package com.cmvr.web.controller.api;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.test.enums.ActionEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "边缘--API操作")
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class EdgeDeviceController extends BaseController {
@ApiOperation("查询操作内容")
@GetMapping("/action")
public AjaxResult getAction() {
return success(ActionEnum.toList());
}
}

View File

@ -0,0 +1,55 @@
package com.cmvr.web.controller.api;
import com.alibaba.fastjson2.JSON;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.edge.client.model.biohead.EdgeFacialExpressionVO;
import com.cmvr.edge.client.service.EdgeBioHeadService;
import com.cmvr.edge.client.service.EdgeDexHandService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@Api(tags = "边缘--机器人灵巧手")
@RestController
@RequestMapping("/api/dexHand")
@RequiredArgsConstructor
public class EdgeDexHandController extends BaseController {
private final EdgeDexHandService edgeDexHandService;
@ApiOperation("获取灵巧手状态信息")
@GetMapping("/status")
public AjaxResult status(
@RequestParam("deviceId") String deviceId,
@RequestParam("terminalId") String terminalId
) {
return success(JSON.parseObject(JSON.toJSONString(edgeDexHandService.getStatus(terminalId, deviceId)), Map.class));
}
@ApiOperation("设置灵巧手弯曲角度")
@GetMapping("/angle")
public AjaxResult setAngle(
@RequestParam("deviceId") String deviceId,
@RequestParam("terminalId") String terminalId,
@RequestParam("id") int id,
@RequestParam("value") float value
) {
edgeDexHandService.setDexHandAngle(terminalId, deviceId, id, value);
return success("ok");
}
@ApiOperation("获取灵巧手按压力信息")
@GetMapping("/sensor")
public AjaxResult sensor(
@RequestParam("deviceId") String deviceId,
@RequestParam("terminalId") String terminalId
) {
return success(JSON.parseObject(edgeDexHandService.getSensorData(terminalId, deviceId), Map.class));
}
}

View File

@ -0,0 +1,84 @@
package com.cmvr.web.controller.api;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.edge.client.model.EdgeCommonVO;
import com.cmvr.edge.client.model.microphone.EdgeMicrophoneVolumeVO;
import com.cmvr.edge.client.service.EdgeMicrophoneService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
/**
* 麦克风管理
*/
@Api(tags = "边缘--麦克风")
@RestController
@RequestMapping("/api/Microphone")
@RequiredArgsConstructor
public class EdgeMicrophoneController {
private final EdgeMicrophoneService microphoneService;
@ApiOperation("获取麦克风状态")
@PreAuthorize("@ss.hasPermi('system:microphone:query')")
@GetMapping("/status")
public AjaxResult getStatus(@ApiParam(value = "终端设备ID", required = true) @RequestParam String terminalId, @ApiParam (value = "设备ID", required = true) @RequestParam String deviceId) {
EdgeCommonVO edgeCommonVO = new EdgeCommonVO();
edgeCommonVO.setTerminalId(terminalId);
edgeCommonVO.setDeviceId(deviceId);
return AjaxResult.success(microphoneService.getStatus(edgeCommonVO));
}
@ApiOperation("开始录音")
@PreAuthorize("@ss.hasPermi('system:microphone:record')")
@PostMapping("/start")
public AjaxResult startRecord(@RequestBody EdgeCommonVO edgeCommonVO) {
String filePath = microphoneService.startRecord(edgeCommonVO);
return AjaxResult.success(filePath);
}
@ApiOperation("停止录音")
@PreAuthorize("@ss.hasPermi('system:microphone:stop')")
@PostMapping("/stop")
public AjaxResult stopRecord(@RequestBody EdgeCommonVO edgeCommonVO) {
microphoneService.stopRecord(edgeCommonVO);
return AjaxResult.success();
}
@ApiOperation("暂停录音")
@PreAuthorize("@ss.hasPermi('system:microphone:pause')")
@PostMapping("/pause")
public AjaxResult pauseRecord(@RequestBody EdgeCommonVO edgeCommonVO) {
microphoneService.pauseRecord(edgeCommonVO);
return AjaxResult.success();
}
@ApiOperation("恢复录音")
@PreAuthorize("@ss.hasPermi('system:microphone:resume')")
@PostMapping("/resume")
public AjaxResult resumeRecord(@RequestBody EdgeCommonVO edgeCommonVO) {
microphoneService.resumeRecord(edgeCommonVO);
return AjaxResult.success();
}
@ApiOperation("设置音量")
@PreAuthorize("@ss.hasPermi('system:microphone:volume')")
@PostMapping("/volume")
public AjaxResult setVolume(@RequestBody EdgeMicrophoneVolumeVO edgeMicrophoneVolumeVO) {
microphoneService.setVolume(edgeMicrophoneVolumeVO);
return AjaxResult.success();
}
@ApiOperation("获取音量")
@PreAuthorize("@ss.hasPermi('system:microphone:volume')")
@GetMapping("/volume")
public AjaxResult getVolume(@ApiParam(value = "终端设备ID", required = true) @RequestParam String terminalId, @ApiParam (value = "设备ID", required = true) @RequestParam String deviceId) {
EdgeCommonVO edgeCommonVO = new EdgeCommonVO();
edgeCommonVO.setTerminalId(terminalId);
edgeCommonVO.setDeviceId(deviceId);
return AjaxResult.success(microphoneService.getVolume(edgeCommonVO));
}
}

View File

@ -0,0 +1,144 @@
package com.cmvr.web.controller.api;
import cmvr.api.SpeakerCommand;
import com.cmvr.edge.client.model.EdgeCommonVO;
import com.cmvr.edge.client.model.microphone.EdgeMicrophoneVolumeVO;
import com.cmvr.edge.client.model.speaker.EdgeSpeakerPlayAudioVO;
import com.cmvr.edge.client.service.EdgeSpeakerService;
import com.cmvr.common.core.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/**
* 扬声器管理
*
* @author cmvr
*/
@Api(tags = "边缘--扬声器")
@RestController
@RequestMapping("/api/Speaker")
@RequiredArgsConstructor
public class EdgeSpeakerController {
private final EdgeSpeakerService speakerService;
@ApiOperation("获取扬声器状态")
@PreAuthorize("@ss.hasPermi('system:speaker:query')")
@GetMapping("/status")
public AjaxResult getStatus(
@ApiParam(value = "终端设备ID", required = true)
@RequestParam String terminalId,
@ApiParam(value = "设备ID", required = true)
@RequestParam String deviceId) {
try {
// 获取扬声器状态
SpeakerCommand.GetSpeakerStateCommand.Feedback feedback = speakerService.getStatus(terminalId, deviceId);
SpeakerCommand.SpeakerState state = feedback.getState();
// 构建返回结果
Map<String, Object> result = new HashMap<>();
// 添加 header 信息
Map<String, Object> header = new HashMap<>();
header.put("deviceId", deviceId);
header.put("timestamp", feedback.getHeader().getTimestamp().getSeconds());
result.put("header", header);
// 添加 state 信息
Map<String, Object> stateMap = new HashMap<>();
stateMap.put("isInitialized", state.getIsInitialized());
stateMap.put("isRunning", state.getIsRunning());
stateMap.put("isDecoding", state.getIsDecoding());
stateMap.put("isPaused", state.getIsPaused());
stateMap.put("volume", state.getVolume());
stateMap.put("errorMessage", state.getErrorMessage());
result.put("state", stateMap);
return AjaxResult.success(result);
} catch (Exception e) {
return AjaxResult.error("获取扬声器状态失败:" + e.getMessage());
}
}
/**
* 播放音频
*/
@ApiOperation("播放音频")
@PreAuthorize("@ss.hasPermi('system:speaker:play')")
@PostMapping("/play")
public AjaxResult playAudio(@RequestBody EdgeSpeakerPlayAudioVO edgeSpeakerPlayAudioVO) {
speakerService.playAudio(edgeSpeakerPlayAudioVO.getTerminalId(), edgeSpeakerPlayAudioVO.getDeviceId(), edgeSpeakerPlayAudioVO.getAudioPath());
return AjaxResult.success();
}
/**
* 停止播放
*/
@ApiOperation("停止播放")
@PreAuthorize("@ss.hasPermi('system:speaker:stop')")
@PostMapping("/stop")
public AjaxResult stopPlayback(@RequestBody EdgeCommonVO edgeCommonVO) {
speakerService.stopPlayback(edgeCommonVO.getTerminalId(), edgeCommonVO.getDeviceId());
return AjaxResult.success();
}
/**
* 暂停播放
*/
@ApiOperation("暂停播放")
@PreAuthorize("@ss.hasPermi('system:speaker:pause')")
@PostMapping("/pause")
public AjaxResult pausePlayback(@RequestBody EdgeCommonVO edgeCommonVO) {
speakerService.pausePlayback(edgeCommonVO.getTerminalId(), edgeCommonVO.getDeviceId());
return AjaxResult.success();
}
/**
* 恢复播放
*/
@ApiOperation("恢复播放")
@PreAuthorize("@ss.hasPermi('system:speaker:resume')")
@PostMapping("/resume")
public AjaxResult resumePlayback(@RequestBody EdgeCommonVO edgeCommonVO) {
speakerService.resumePlayback(edgeCommonVO.getTerminalId(), edgeCommonVO.getDeviceId());
return AjaxResult.success();
}
/**
* 设置音量
*/
@ApiOperation("设置音量")
@PreAuthorize("@ss.hasPermi('system:speaker:volume')")
@PostMapping("/volume")
public AjaxResult setVolume(@RequestBody EdgeMicrophoneVolumeVO edgeMicrophoneVolumeVO) {
speakerService.setVolume(edgeMicrophoneVolumeVO.getTerminalId(), edgeMicrophoneVolumeVO.getDeviceId(), edgeMicrophoneVolumeVO.getVolume());
return AjaxResult.success();
}
/**
* 获取音量
*/
@ApiOperation("获取音量")
@PreAuthorize("@ss.hasPermi('system:speaker:volume')")
@GetMapping("/volume")
public AjaxResult getVolume(
@ApiParam(value = "终端设备ID", required = true)
@RequestParam String terminalId,
@ApiParam(value = "设备ID", required = true)
@RequestParam String deviceId) {
return AjaxResult.success(speakerService.getVolume(terminalId, deviceId));
}
@ApiOperation("获取所有音频")
@PreAuthorize("@ss.hasPermi('system:speaker:getAll')")
@GetMapping("/getAll")
public AjaxResult getAll() {
return AjaxResult.success(speakerService.getAll());
}
}

View File

@ -0,0 +1,26 @@
package com.cmvr.web.controller.api;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.edge.client.service.EdgeSystemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "边缘--系统功能")
@RestController
@RequestMapping("/api/system")
@RequiredArgsConstructor
public class EdgeSystemController extends BaseController {
private final EdgeSystemService edgeSystemService;
@ApiOperation("停止所有设备")
@GetMapping("/stopAll")
public AjaxResult stopAll(String terminalId) {
return AjaxResult.ok(edgeSystemService.stopAll(terminalId));
}
}

View File

@ -0,0 +1,60 @@
package com.cmvr.web.controller.api;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.llm.model.CallAgentVO;
import com.cmvr.llm.service.LargeModelRemoteService;
import com.cmvr.llm.util.LargeModelFileUploadUtil;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.system.domain.vo.CarIcon;
import com.cmvr.system.service.CarPathFinderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.stream.Collectors;
@Api(tags = "大模型服务")
@RestController
@RequestMapping("/api/call")
@RequiredArgsConstructor
public class LargeModelRemoteController extends BaseController {
private final LargeModelRemoteService largeModelRemoteService;
private final CarPathFinderService carPathFinderService;
@ApiOperation("查找操作路径")
@GetMapping("/path")
public AjaxResult path(
@RequestParam("manufacturer") String manufacturer,
@RequestParam("vehType") String vehType,
@RequestParam("startUi") String startUi,
@RequestParam("targetFeature") String targetFeature
) {
List<CarIcon> path = carPathFinderService.findPath(manufacturer, vehType, startUi, targetFeature);
return AjaxResult.ok(path.stream().map(CarIcon::getIconName).collect(Collectors.joining(" -> ")));
}
@ApiOperation("执行语音转文本工作流")
@PostMapping("/speechToText")
public AjaxResult runSpeechToText(@RequestBody CallAgentVO callAgentVO) {
String result = largeModelRemoteService.runSpeechToTextWorkflow(callAgentVO);
return AjaxResult.success("工作流执行成功", result);
}
@ApiOperation("查询语音转文本结果")
@PostMapping("/result")
public AjaxResult queryResult(@RequestParam("processId") String processId) {
String result = largeModelRemoteService.querySpeechToTextResult(processId);
return AjaxResult.success("查询成功", result);
}
@ApiOperation("上传文件到大模型")
@PostMapping("/upload/large")
public String uploadFileLarge(@RequestPart("file") MultipartFile file) throws Exception {
return LargeModelFileUploadUtil.uploadFile(file.getBytes());
}
}

View File

@ -0,0 +1,123 @@
package com.cmvr.web.controller.api;
import com.cmvr.edge.client.service.AudioService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
/**
* WebRTC 信令 WebSocket 入口
*
* 路径/ws/signaling
*
* 约束
* 1. WebSocket 只传 JSON 信令joinofferanswercandidateheartbeatstop
* 2. WebSocket 禁止传输 PCM 音频
* 3. PCM 音频由 WebRTC 媒体通道进入 Java 后端再由 AudioService gRPC 双向流
*/
@Configuration
@RequiredArgsConstructor
public class WebRtcSignalingController implements WebSocketConfigurer {
private final AudioService audioService;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new SignalingWebSocketHandler(audioService), "/ws/signaling")
.setAllowedOrigins("*");
registry.addHandler(new SignalingWebSocketHandler(audioService), "/ws/audio")
.setAllowedOrigins("*");
}
/**
* 信令处理器这里只处理文本 JSON不处理二进制音频
*/
private static class SignalingWebSocketHandler extends AbstractWebSocketHandler {
private static final Logger log = LoggerFactory.getLogger(SignalingWebSocketHandler.class);
private final AudioService audioService;
private final ObjectMapper objectMapper = new ObjectMapper();
private SignalingWebSocketHandler(AudioService audioService) {
this.audioService = audioService;
}
@Override
public void afterConnectionEstablished(@NotNull WebSocketSession session) {
log.info("WebRTC信令连接建立wsSessionId={}", session.getId());
sendConnected(session);
}
@Override
protected void handleTextMessage(@NotNull WebSocketSession session, @NotNull TextMessage message) {
try {
audioService.handleSignalingMessage(session, message.getPayload());
} catch (Exception e) {
log.error("处理WebRTC信令异常wsSessionId={}", session.getId(), e);
sendError(session, "处理WebRTC信令异常" + e.getMessage());
}
}
@Override
protected void handleBinaryMessage(@NotNull WebSocketSession session, @NotNull BinaryMessage message) {
try {
audioService.handleBrowserAudioMessage(session, message.getPayload());
} catch (Exception e) {
log.error("处理WebSocket音频二进制帧失败wsSessionId={}", session.getId(), e);
sendError(session, "audio binary frame failed: " + e.getMessage());
}
}
@Override
public void handleTransportError(@NotNull WebSocketSession session, @NotNull Throwable exception) {
log.error("WebRTC信令连接传输异常wsSessionId={}", session.getId(), exception);
audioService.handleWebSocketClosed(session);
}
@Override
public void afterConnectionClosed(@NotNull WebSocketSession session, @NotNull CloseStatus status) {
log.info("WebRTC信令连接关闭wsSessionId={}status={}", session.getId(), status);
audioService.handleWebSocketClosed(session);
}
private void sendConnected(WebSocketSession session) {
ObjectNode node = objectMapper.createObjectNode();
node.put("type", "connected");
node.put("timestamp", System.currentTimeMillis());
sendJson(session, node);
}
private void sendError(WebSocketSession session, String message) {
ObjectNode node = objectMapper.createObjectNode();
node.put("type", "error");
node.put("message", message);
node.put("timestamp", System.currentTimeMillis());
sendJson(session, node);
}
private void sendJson(WebSocketSession session, ObjectNode node) {
if (session == null || !session.isOpen()) {
return;
}
try {
synchronized (session) {
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(node)));
}
} catch (Exception e) {
log.error("发送WebRTC信令响应失败wsSessionId={}", session.getId(), e);
}
}
}
}

View File

@ -0,0 +1,94 @@
package com.cmvr.web.controller.common;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.google.code.kaptcha.Producer;
import com.cmvr.common.config.CmvrIotConfig;
import com.cmvr.common.constant.CacheConstants;
import com.cmvr.common.constant.Constants;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.redis.RedisCache;
import com.cmvr.common.utils.sign.Base64;
import com.cmvr.common.utils.uuid.IdUtils;
import com.cmvr.system.service.ISysConfigService;
/**
* 验证码操作处理
*
* @author cmvr-iot
*/
@RestController
public class CaptchaController
{
@Resource(name = "captchaProducer")
private Producer captchaProducer;
@Resource(name = "captchaProducerMath")
private Producer captchaProducerMath;
@Autowired
private RedisCache redisCache;
@Autowired
private ISysConfigService configService;
/**
* 生成验证码
*/
@GetMapping("/captchaImage")
public AjaxResult getCode(HttpServletResponse response) throws IOException
{
AjaxResult ajax = AjaxResult.success();
boolean captchaEnabled = configService.selectCaptchaEnabled();
ajax.put("captchaEnabled", captchaEnabled);
if (!captchaEnabled)
{
return ajax;
}
// 保存验证码信息
String uuid = IdUtils.simpleUUID();
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
String capStr = null, code = null;
BufferedImage image = null;
// 生成验证码
String captchaType = CmvrIotConfig.getCaptchaType();
if ("math".equals(captchaType))
{
String capText = captchaProducerMath.createText();
capStr = capText.substring(0, capText.lastIndexOf("@"));
code = capText.substring(capText.lastIndexOf("@") + 1);
image = captchaProducerMath.createImage(capStr);
}
else if ("char".equals(captchaType))
{
capStr = code = captchaProducer.createText();
image = captchaProducer.createImage(capStr);
}
redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
// 转换流信息写出
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
try
{
ImageIO.write(image, "jpg", os);
}
catch (IOException e)
{
return AjaxResult.error(e.getMessage());
}
ajax.put("uuid", uuid);
ajax.put("img", Base64.encode(os.toByteArray()));
return ajax;
}
}

View File

@ -0,0 +1,140 @@
package com.cmvr.web.controller.common;
import com.cmvr.common.config.CmvrIotConfig;
import com.cmvr.common.constant.Constants;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.utils.StringUtils;
import com.cmvr.common.utils.file.FileUploadUtils;
import com.cmvr.common.utils.file.FileUtils;
import com.cmvr.framework.config.ServerConfig;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
@Api(tags = "通用请求处理")
@RestController
@RequestMapping("/common")
@RequiredArgsConstructor
public class CommonController {
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
private final ServerConfig serverConfig;
private static final String FILE_DELIMETER = ",";
/**
* 通用下载请求
*
* @param fileName 文件名称
* @param delete 是否删除
*/
@GetMapping("/download")
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) {
try {
if (!FileUtils.checkAllowDownload(fileName)) {
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
}
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
String filePath = CmvrIotConfig.getDownloadPath() + fileName;
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, realFileName);
FileUtils.writeBytes(filePath, response.getOutputStream());
if (delete) {
FileUtils.deleteFile(filePath);
}
} catch (Exception e) {
log.error("下载文件失败", e);
}
}
/**
* 通用上传请求单个
*/
@PostMapping("/upload")
public AjaxResult uploadFile(MultipartFile file) throws Exception {
try {
// 上传文件路径
String filePath = CmvrIotConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
AjaxResult ajax = AjaxResult.success();
ajax.put("url", url);
ajax.put("fileName", fileName);
ajax.put("newFileName", FileUtils.getName(fileName));
ajax.put("originalFilename", file.getOriginalFilename());
return ajax;
} catch (Exception e) {
return AjaxResult.error(e.getMessage());
}
}
/**
* 通用上传请求多个
*/
@PostMapping("/uploads")
public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception {
try {
// 上传文件路径
String filePath = CmvrIotConfig.getUploadPath();
List<String> urls = new ArrayList<String>();
List<String> fileNames = new ArrayList<String>();
List<String> newFileNames = new ArrayList<String>();
List<String> originalFilenames = new ArrayList<String>();
for (MultipartFile file : files) {
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
urls.add(url);
fileNames.add(fileName);
newFileNames.add(FileUtils.getName(fileName));
originalFilenames.add(file.getOriginalFilename());
}
AjaxResult ajax = AjaxResult.success();
ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
return ajax;
} catch (Exception e) {
return AjaxResult.error(e.getMessage());
}
}
/**
* 本地资源通用下载
*/
@GetMapping("/download/resource")
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
throws Exception {
try {
if (!FileUtils.checkAllowDownload(resource)) {
throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
}
// 本地资源路径
String localPath = CmvrIotConfig.getProfile();
// 数据库资源地址
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
// 下载名称
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, downloadName);
FileUtils.writeBytes(downloadPath, response.getOutputStream());
} catch (Exception e) {
log.error("下载文件失败", e);
}
}
}

View File

@ -0,0 +1,115 @@
package com.cmvr.web.controller.device;
import java.util.List;
import com.cmvr.device.domain.vo.ProfileVo;
import com.cmvr.device.domain.vo.TeMechanicalArmVo;
import com.cmvr.edge.client.service.EdgeSystemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.device.domain.DeDeviceProfile;
import com.cmvr.device.service.IDeDeviceProfileService;
import com.cmvr.common.core.page.TableDataInfo;
/**
* 设备配置信息Controller
*
* @author cmvr-iot
* @date 2025-05-09
*/
@RestController
@RequestMapping("/device/profile")
@RequiredArgsConstructor
@Api(tags = "设备--配置信息")
public class DeDeviceProfileController extends BaseController
{
private final IDeDeviceProfileService deDeviceProfileService;
private final EdgeSystemService systemService;
/**
* 查询设备配置信息列表
*/
@PreAuthorize("@ss.hasPermi('device:profile:list')")
@GetMapping("/list")
@ApiOperation("查询设备信息列表")
public TableDataInfo list(DeDeviceProfile deDeviceProfile)
{
startPage();
List<ProfileVo> list = deDeviceProfileService.selectDeDeviceProfileList(deDeviceProfile);
return getDataTable(list);
}
/**
* 根据设备id获取设备详细配置信息
*/
@PreAuthorize("@ss.hasPermi('device:profile:query')")
@GetMapping("/{id}")
@ApiOperation("根据设备id获取当前设备配置信息")
public AjaxResult getInfo(@PathVariable String id)
{
return success(deDeviceProfileService.selectDeDeviceProfileById(id));
}
/**
* 根据设备id和备注获取设备详细配置信息
*/
@PreAuthorize("@ss.hasPermi('device:profile:query')")
@GetMapping("/parameterInfo")
@ApiOperation("根据设备id获取当前设备配置信息")
public AjaxResult getParameterInfo(@RequestParam String id, @RequestParam String remark)
{
return success(deDeviceProfileService.selectProfileByIdAndRemark(id,remark));
}
/**
* 新增设备配置信息
*/
@PreAuthorize("@ss.hasPermi('device:profile:add')")
@Log(title = "设备配置信息", businessType = BusinessType.INSERT)
@ApiOperation("新增设备信息")
@PostMapping
public AjaxResult add(@RequestBody List<DeDeviceProfile> deDeviceProfiles)
{
return toAjax(deDeviceProfileService.insertDeDeviceProfile(deDeviceProfiles));
}
/**
* 修改设备配置信息
*/
@PreAuthorize("@ss.hasPermi('device:profile:edit')")
@Log(title = "设备配置信息", businessType = BusinessType.UPDATE)
@ApiOperation("修改设备信息")
@PutMapping
public AjaxResult edit(@RequestBody List<DeDeviceProfile> deDeviceProfiles)
{
return toAjax(deDeviceProfileService.updateDeDeviceProfile(deDeviceProfiles));
}
/**
* 删除设备配置信息
*/
@PreAuthorize("@ss.hasPermi('device:profile:remove')")
@Log(title = "设备配置信息", businessType = BusinessType.DELETE)
@ApiOperation("删除设备配置信息")
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
return toAjax(deDeviceProfileService.deleteDeDeviceProfileByIds(ids));
}
}

View File

@ -0,0 +1,122 @@
package com.cmvr.web.controller.device;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.cmvr.edge.client.service.EdgeSystemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.device.domain.DeDeviceRegistration;
import com.cmvr.device.service.IDeDeviceRegistrationService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
/**
* 设备注册Controller
*
* @author cmvr-iot
* @date 2025-05-08
*/
@RestController
@RequestMapping("/device/register")
@RequiredArgsConstructor
@Api(tags = "设备--注册")
public class DeDeviceRegistrationController extends BaseController
{
@Autowired
private IDeDeviceRegistrationService deDeviceRegistrationService;
private final EdgeSystemService systemService;
/**
* 查询设备注册列表
*/
@ApiOperation("查询设备注册列表")
@PreAuthorize("@ss.hasPermi('device:register:list')")
@GetMapping("/list")
public TableDataInfo list(DeDeviceRegistration deDeviceRegistration)
{
startPage();
List<DeDeviceRegistration> list = deDeviceRegistrationService.selectDeDeviceRegistrationList(deDeviceRegistration);
return getDataTable(list);
}
/**
* 导出设备注册列表
*/
@ApiOperation("导出设备注册列表")
@PreAuthorize("@ss.hasPermi('device:register:export')")
@Log(title = "设备注册", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, DeDeviceRegistration deDeviceRegistration)
{
List<DeDeviceRegistration> list = deDeviceRegistrationService.selectDeDeviceRegistrationList(deDeviceRegistration);
ExcelUtil<DeDeviceRegistration> util = new ExcelUtil<DeDeviceRegistration>(DeDeviceRegistration.class);
util.exportExcel(response, list, "设备注册数据");
}
/**
* 获取设备注册详细信息
*/
@ApiOperation("获取设备注册详细信息")
@PreAuthorize("@ss.hasPermi('device:register:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id)
{
return success(deDeviceRegistrationService.selectDeDeviceRegistrationById(id));
}
/**
* 新增设备注册
*/
@ApiOperation("新增设备注册")
@PreAuthorize("@ss.hasPermi('device:register:add')")
@Log(title = "设备注册", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody DeDeviceRegistration deDeviceRegistration)
{
return toAjax(deDeviceRegistrationService.insertDeDeviceRegistration(deDeviceRegistration));
}
/**
* 修改设备注册
*/
@ApiOperation("修改设备注册")
@PreAuthorize("@ss.hasPermi('device:register:edit')")
@Log(title = "设备注册", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody DeDeviceRegistration deDeviceRegistration)
{
return toAjax(deDeviceRegistrationService.updateDeDeviceRegistration(deDeviceRegistration));
}
/**
* 删除设备注册
*/
@ApiOperation("删除设备注册")
@PreAuthorize("@ss.hasPermi('device:register:remove')")
@Log(title = "设备注册", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
return toAjax(deDeviceRegistrationService.deleteDeDeviceRegistrationByIds(ids));
}
}

View File

@ -0,0 +1,102 @@
package com.cmvr.web.controller.device;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.device.domain.DeDeviceTerminalConfig;
import com.cmvr.device.service.IDeDeviceTerminalConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 设备终端配置Controller
*
* @author cmvr-iot
* @date 2025-05-08
*/
@RestController
@RequestMapping("/device/terminal")
@RequiredArgsConstructor
@Api(tags = "设备--终端配置")
public class DeDeviceTerminalConfigController extends BaseController {
@Autowired
private IDeDeviceTerminalConfigService deDeviceTerminalConfigService;
/**
* 查询设备终端配置列表
*/
@ApiOperation("查询设备终端配置列表")
@PreAuthorize("@ss.hasPermi('device:terminal:list')")
@GetMapping("/list")
public TableDataInfo list(DeDeviceTerminalConfig deDeviceTerminalConfig) {
startPage();
List<DeDeviceTerminalConfig> list = deDeviceTerminalConfigService.selectDeDeviceTerminalConfigList(deDeviceTerminalConfig);
return getDataTable(list);
}
/**
* 导出设备终端配置列表
*/
@ApiOperation("导出设备终端配置列表")
@PreAuthorize("@ss.hasPermi('device:terminal:export')")
@Log(title = "设备终端配置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, DeDeviceTerminalConfig deDeviceTerminalConfig) {
List<DeDeviceTerminalConfig> list = deDeviceTerminalConfigService.selectDeDeviceTerminalConfigList(deDeviceTerminalConfig);
ExcelUtil<DeDeviceTerminalConfig> util = new ExcelUtil<DeDeviceTerminalConfig>(DeDeviceTerminalConfig.class);
util.exportExcel(response, list, "设备终端配置数据");
}
/**
* 获取设备终端配置详细信息
*/
@ApiOperation("获取设备终端配置详细信息")
@PreAuthorize("@ss.hasPermi('device:terminal:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id) {
return success(deDeviceTerminalConfigService.selectDeDeviceTerminalConfigById(id));
}
/**
* 新增设备终端配置
*/
@ApiOperation("新增设备终端配置")
@PreAuthorize("@ss.hasPermi('device:terminal:add')")
@Log(title = "设备终端配置", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody DeDeviceTerminalConfig deDeviceTerminalConfig) {
return toAjax(deDeviceTerminalConfigService.insertDeDeviceTerminalConfig(deDeviceTerminalConfig));
}
/**
* 修改设备终端配置
*/
@ApiOperation("修改设备终端数据")
@PreAuthorize("@ss.hasPermi('device:terminal:edit')")
@Log(title = "设备终端配置", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody DeDeviceTerminalConfig deDeviceTerminalConfig) {
return toAjax(deDeviceTerminalConfigService.updateDeDeviceTerminalConfig(deDeviceTerminalConfig));
}
/**
* 删除设备终端配置
*/
@ApiOperation("删除设备终端配置")
@PreAuthorize("@ss.hasPermi('device:terminal:remove')")
@Log(title = "设备终端配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(deDeviceTerminalConfigService.deleteDeDeviceTerminalConfigByIds(ids));
}
}

View File

@ -0,0 +1,105 @@
package com.cmvr.web.controller.device;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.poi.ExcelUtil;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.device.domain.DeRobotConfig;
import com.cmvr.device.service.IDeRobotConfigService;
import static com.cmvr.common.core.domain.AjaxResult.success;
/**
* 机器人配置Controller
*
* @author cmvr-iot
* @date 2025-09-09
*/
@RestController
@RequestMapping("/device/robot")
public class DeRobotConfigController extends BaseController
{
@Autowired
private IDeRobotConfigService deRobotConfigService;
/**
* 查询机器人配置列表
*/
@PreAuthorize("@ss.hasPermi('device:robot:list')")
@GetMapping("/list")
public AjaxResult list(DeRobotConfig deRobotConfig)
{
List<DeRobotConfig> list = deRobotConfigService.selectDeRobotConfigList(deRobotConfig);
return success(list);
}
/**
* 导出机器人配置列表
*/
@PreAuthorize("@ss.hasPermi('device:robot:export')")
@Log(title = "机器人配置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, DeRobotConfig deRobotConfig)
{
List<DeRobotConfig> list = deRobotConfigService.selectDeRobotConfigList(deRobotConfig);
ExcelUtil<DeRobotConfig> util = new ExcelUtil<DeRobotConfig>(DeRobotConfig.class);
util.exportExcel(response, list, "机器人配置数据");
}
/**
* 获取机器人配置详细信息
*/
@PreAuthorize("@ss.hasPermi('device:robot:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id)
{
return success(deRobotConfigService.selectDeRobotConfigById(id));
}
/**
* 新增机器人配置
*/
@PreAuthorize("@ss.hasPermi('device:robot:add')")
@Log(title = "机器人配置", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody DeRobotConfig deRobotConfig)
{
return toAjax(deRobotConfigService.insertDeRobotConfig(deRobotConfig));
}
/**
* 修改机器人配置
*/
@PreAuthorize("@ss.hasPermi('device:robot:edit')")
@Log(title = "机器人配置", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody DeRobotConfig deRobotConfig)
{
return toAjax(deRobotConfigService.updateDeRobotConfig(deRobotConfig));
}
/**
* 删除机器人配置
*/
@PreAuthorize("@ss.hasPermi('device:robot:remove')")
@Log(title = "机器人配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
return toAjax(deRobotConfigService.deleteDeRobotConfigByIds(ids));
}
}

View File

@ -0,0 +1,33 @@
package com.cmvr.web.controller.evaluation;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.evaluation.model.domain.AeEvaluation;
import com.cmvr.evaluation.service.AeCallbackService;
import com.cmvr.evaluation.service.IAeEvaluationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "AI评估")
@RestController
@RequestMapping("/evaluation")
@RequiredArgsConstructor
public class AeEvaluationController extends BaseController {
private final IAeEvaluationService aeEvaluationService;
private final AeCallbackService aeCallbackService;
@ApiOperation("回调AI评估")
@PostMapping("/callback")
public AjaxResult list(@RequestBody AeEvaluation aeEvaluation) {
aeCallbackService.callback(aeEvaluation);
return AjaxResult.ok();
}
}

View File

@ -0,0 +1,59 @@
package com.cmvr.web.controller.evaluation;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.evaluation.model.dto.AeIndicatorCreateDTO;
import com.cmvr.evaluation.model.dto.AeIndicatorUpdateDTO;
import com.cmvr.evaluation.service.AeIndicatorService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@Api(tags = "评价管理--指标库")
@RestController
@RequestMapping("/evaluate/indicator")
@RequiredArgsConstructor
public class AeIndicatorController extends BaseController {
private final AeIndicatorService indicatorService;
@ApiOperation("根据父id查询指标")
@GetMapping("/getIndicatorByParentId")
public AjaxResult getIndicatorByParentId(@RequestParam Long parentId, @RequestParam Integer type) {
if (parentId == null || type == null) {
return AjaxResult.error("参数不能为空");
}
return success(indicatorService.selectIndicatorByParentId(parentId, type));
}
@ApiOperation("新增指标")
@PostMapping("/indicator/insert")
public AjaxResult insertIndicator(@Valid @RequestBody AeIndicatorCreateDTO createDTO) {
return success(indicatorService.saveIndicator(createDTO));
}
@ApiOperation("根据ID级联删除删除当前指标及其所有后代指标子/孙级)")
@DeleteMapping("/{id}")
public AjaxResult removeIndicator(@PathVariable Long id) {
if (id == null) {
return AjaxResult.error("id不能为空");
}
return toAjax(indicatorService.removeIndicator(id));
}
@ApiOperation("修改指标")
@PutMapping
public AjaxResult updateIndicator(@Valid @RequestBody AeIndicatorUpdateDTO updateDTO) {
return toAjax(indicatorService.updateIndicator(updateDTO));
}
@ApiOperation("获取指定parentId下指定level层级的指标")
@GetMapping("/getChildrenByParentIdWithLevelLimit")
public AjaxResult getChildrenByParentIdWithLevelLimit(@RequestParam Long parentId, @RequestParam Integer maxLevel, @RequestParam Integer type) {
return success(indicatorService.getChildrenByParentIdWithLevelLimit(parentId, maxLevel, type));
}
}

View File

@ -0,0 +1,114 @@
package com.cmvr.web.controller.inspection;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.inspection.domain.InspectionAlarm;
import com.cmvr.inspection.domain.vo.InspectionAlarmVo;
import com.cmvr.inspection.service.IInspectionAlarmService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
/**
* 巡检告警Controller
*
* @author cmvr-iot
* @since 2026-05-29
*/
@RestController
@RequestMapping("/inspection/alarm")
@Api(tags = "智能巡检--告警管理")
public class InspectionAlarmController extends BaseController
{
@Autowired
private IInspectionAlarmService inspectionAlarmService;
/**
* 查询巡检告警列表
*/
@ApiOperation("查询巡检告警列表")
@PreAuthorize("@ss.hasPermi('inspection:alarm:list')")
@GetMapping("/list")
public TableDataInfo list(InspectionAlarm inspectionAlarm)
{
startPage();
List<InspectionAlarmVo> list = inspectionAlarmService.selectInspectionAlarmList(inspectionAlarm);
return getDataTable(list);
}
/**
* 导出巡检告警列表
*/
@ApiOperation("导出巡检告警列表")
@PreAuthorize("@ss.hasPermi('inspection:alarm:export')")
@Log(title = "巡检告警", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, InspectionAlarm inspectionAlarm)
{
List<InspectionAlarmVo> list = inspectionAlarmService.selectInspectionAlarmList(inspectionAlarm);
ExcelUtil<InspectionAlarmVo> util = new ExcelUtil<>(InspectionAlarmVo.class);
util.exportExcel(response, list, "巡检告警数据");
}
/**
* 获取巡检告警详细信息
*/
@ApiOperation("获取巡检告警详细信息")
@PreAuthorize("@ss.hasPermi('inspection:alarm:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id)
{
return success(inspectionAlarmService.selectInspectionAlarmById(id));
}
/**
* 新增巡检告警
*/
@ApiOperation("新增巡检告警")
@PreAuthorize("@ss.hasPermi('inspection:alarm:add')")
@Log(title = "巡检告警", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody InspectionAlarm inspectionAlarm)
{
return toAjax(inspectionAlarmService.insertInspectionAlarm(inspectionAlarm));
}
/**
* 修改巡检告警
*/
@ApiOperation("修改巡检告警")
@PreAuthorize("@ss.hasPermi('inspection:alarm:edit')")
@Log(title = "巡检告警", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody InspectionAlarm inspectionAlarm)
{
return toAjax(inspectionAlarmService.updateInspectionAlarm(inspectionAlarm));
}
/**
* 删除巡检告警
*/
@ApiOperation("删除巡检告警")
@PreAuthorize("@ss.hasPermi('inspection:alarm:remove')")
@Log(title = "巡检告警", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
return toAjax(inspectionAlarmService.deleteInspectionAlarmByIds(ids));
}
}

View File

@ -0,0 +1,123 @@
package com.cmvr.web.controller.inspection;
import com.cmvr.common.annotation.Anonymous;
import com.cmvr.inspection.domain.dto.alert.AlertEnvelope;
import com.cmvr.inspection.exception.DetectionAlertBadRequestException;
import com.cmvr.inspection.service.IInspectionDetectionAlertService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* cmvr_edge_ai 检测报警推送入口
*
* 该接口由边缘服务主动调用使用HTTP状态码表达处理结果不使用项目通用AjaxResult包装
*/
@Slf4j
@Anonymous
@RestController
@RequiredArgsConstructor
@Api(tags = "智能巡检--PPE报警接收")
public class InspectionDetectionAlertController
{
/** 包含Base64图片的JSON请求最大允许20MB防止异常请求耗尽服务端内存。 */
private static final int MAX_REQUEST_BYTES = 20 * 1024 * 1024;
private final IInspectionDetectionAlertService detectionAlertService;
private final ObjectMapper objectMapper;
/**
* 接收PPE违规报警重复事件视为已处理仍返回204避免边缘端持续重试
*/
@ApiOperation("接收边缘AI的PPE违规报警")
@PostMapping(value = "/v1/detection-alerts", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> receive(
@RequestHeader(value = "Idempotency-Key", required = false) String idempotencyKey,
HttpServletRequest request)
{
try
{
String requestBody = readRequestBody(request);
AlertEnvelope envelope = objectMapper.readValue(requestBody, AlertEnvelope.class);
detectionAlertService.receive(envelope, idempotencyKey);
return ResponseEntity.noContent().build();
}
catch (JsonProcessingException | DetectionAlertBadRequestException ex)
{
log.warn("拒绝不合法的PPE报警请求idempotencyKey={},原因={}", idempotencyKey, ex.getMessage());
return ResponseEntity.badRequest().build();
}
catch (DuplicateKeyException ex)
{
// 预查与插入之间仍可能发生并发由数据库唯一索引完成最终幂等
log.info("忽略并发重复的PPE报警idempotencyKey={}", idempotencyKey);
return ResponseEntity.noContent().build();
}
catch (IOException ex)
{
log.warn("读取PPE报警请求失败idempotencyKey={},原因={}", idempotencyKey, ex.getMessage());
return ResponseEntity.badRequest().build();
}
catch (Exception ex)
{
log.error("PPE报警处理暂时失败idempotencyKey={}", idempotencyKey, ex);
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();
}
}
private String readRequestBody(HttpServletRequest request) throws IOException
{
long contentLength = request.getContentLengthLong();
if (contentLength > MAX_REQUEST_BYTES)
{
throw new DetectionAlertBadRequestException("请求体不能超过20MB");
}
try (ServletInputStream inputStream = request.getInputStream();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(initialCapacity(contentLength)))
{
byte[] buffer = new byte[8192];
int total = 0;
int length;
while ((length = inputStream.read(buffer)) != -1)
{
total += length;
if (total > MAX_REQUEST_BYTES)
{
throw new DetectionAlertBadRequestException("请求体不能超过20MB");
}
outputStream.write(buffer, 0, length);
}
if (total == 0)
{
throw new DetectionAlertBadRequestException("请求体不能为空");
}
return new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
}
}
private int initialCapacity(long contentLength)
{
if (contentLength <= 0 || contentLength > MAX_REQUEST_BYTES)
{
return 8192;
}
return (int) contentLength;
}
}

View File

@ -0,0 +1,114 @@
package com.cmvr.web.controller.inspection;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.inspection.domain.InspectionMap;
import com.cmvr.inspection.domain.vo.InspectionMapVo;
import com.cmvr.inspection.service.IInspectionMapService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
/**
* 巡检地图Controller
*
* @author cmvr-iot
* @since 2026-05-29
*/
@RestController
@RequestMapping("/inspection/map")
@Api(tags = "智能巡检--地图管理")
public class InspectionMapController extends BaseController
{
@Autowired
private IInspectionMapService inspectionMapService;
/**
* 查询巡检地图列表
*/
@ApiOperation("查询巡检地图列表")
@PreAuthorize("@ss.hasPermi('inspection:map:list')")
@GetMapping("/list")
public TableDataInfo list(InspectionMap inspectionMap)
{
startPage();
List<InspectionMapVo> list = inspectionMapService.selectInspectionMapList(inspectionMap);
return getDataTable(list);
}
/**
* 导出巡检地图列表
*/
@ApiOperation("导出巡检地图列表")
@PreAuthorize("@ss.hasPermi('inspection:map:export')")
@Log(title = "巡检地图", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, InspectionMap inspectionMap)
{
List<InspectionMapVo> list = inspectionMapService.selectInspectionMapList(inspectionMap);
ExcelUtil<InspectionMapVo> util = new ExcelUtil<>(InspectionMapVo.class);
util.exportExcel(response, list, "巡检地图数据");
}
/**
* 获取巡检地图详细信息
*/
@ApiOperation("获取巡检地图详细信息")
@PreAuthorize("@ss.hasPermi('inspection:map:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id)
{
return success(inspectionMapService.selectInspectionMapById(id));
}
/**
* 新增巡检地图
*/
@ApiOperation("新增巡检地图")
@PreAuthorize("@ss.hasPermi('inspection:map:add')")
@Log(title = "巡检地图", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody InspectionMap inspectionMap)
{
return toAjax(inspectionMapService.insertInspectionMap(inspectionMap));
}
/**
* 修改巡检地图
*/
@ApiOperation("修改巡检地图")
@PreAuthorize("@ss.hasPermi('inspection:map:edit')")
@Log(title = "巡检地图", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody InspectionMap inspectionMap)
{
return toAjax(inspectionMapService.updateInspectionMap(inspectionMap));
}
/**
* 删除巡检地图
*/
@ApiOperation("删除巡检地图")
@PreAuthorize("@ss.hasPermi('inspection:map:remove')")
@Log(title = "巡检地图", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
return toAjax(inspectionMapService.deleteInspectionMapByIds(ids));
}
}

View File

@ -0,0 +1,126 @@
package com.cmvr.web.controller.inspection;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.inspection.domain.dto.InspectionResultQuery;
import com.cmvr.inspection.domain.dto.InspectionResultReviewRequest;
import com.cmvr.inspection.domain.vo.InspectionResultVo;
import com.cmvr.inspection.service.IInspectionResultService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 巡检结果人工复核和任务报表接口
*/
@RestController
@RequestMapping("/inspection/result")
@Api(tags = "智能巡检--巡检结果", description = "巡检结果查询、人工复核、三级告警统计和报表导出")
@ApiResponses({
@ApiResponse(code = 200, message = "请求处理成功"),
@ApiResponse(code = 400, message = "请求参数或状态不合法"),
@ApiResponse(code = 401, message = "未登录或登录已失效"),
@ApiResponse(code = 403, message = "无接口权限"),
@ApiResponse(code = 500, message = "系统内部异常")
})
@RequiredArgsConstructor
public class InspectionResultController extends BaseController
{
private final IInspectionResultService inspectionResultService;
@ApiOperation(value = "查询巡检结果列表",
notes = "分页查询PPE、仪表读数和人工判断结果查询条件均为可选结果按检测时间倒序。"
+ "返回rows元素为InspectionResultVo包含taskName任务名称和evidenceType主要证据类型"
+ "完整mediaList仅在详情接口返回")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "页码从1开始", dataType = "int", paramType = "query", example = "1"),
@ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "int", paramType = "query", example = "10"),
@ApiImplicitParam(name = "taskInstanceId", value = "巡检任务实例数据库ID", dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "taskId", value = "巡检任务ID", dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "itemId", value = "检测项ID", dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "resultType", value = "结果类型PPE、METER、MANUAL", dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "resultStatus", value = "状态PENDING、NORMAL、ABNORMAL、RECOGNIZE_FAILED", dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "alarmLevel", value = "告警级别1提示、2警告、3严重", dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "resultName", value = "检查名称,支持模糊查询", dataType = "string", paramType = "query")
})
@PreAuthorize("@ss.hasPermi('inspection:result:list')")
@GetMapping("/list")
public TableDataInfo list(@ApiParam("巡检结果查询条件") InspectionResultQuery query)
{
startPage();
return getDataTable(inspectionResultService.selectResultList(query));
}
@ApiOperation(value = "查询巡检结果详情",
notes = "返回结构化巡检结果及按顺序排列的全部图片、视频证据",
response = InspectionResultVo.class)
@PreAuthorize("@ss.hasPermi('inspection:result:query')")
@GetMapping("/{id}")
public AjaxResult getInfo(@ApiParam(value = "巡检结果ID", required = true)
@PathVariable String id)
{
return success(inspectionResultService.selectResultById(id));
}
@ApiOperation(value = "提交人工复核结果",
notes = "仅PENDING或RECOGNIZE_FAILED状态可复核。ABNORMAL必须传alarmLevelreviewVersion用于并发控制")
@PreAuthorize("@ss.hasPermi('inspection:result:review')")
@Log(title = "巡检结果人工复核", businessType = BusinessType.UPDATE)
@PutMapping("/{id}/review")
public AjaxResult review(@ApiParam(value = "巡检结果ID", required = true)
@PathVariable String id,
@ApiParam(value = "人工复核内容", required = true)
@Validated @RequestBody InspectionResultReviewRequest request)
{
return success(inspectionResultService.review(id, request));
}
@ApiOperation(value = "查询巡检任务报表汇总",
notes = "返回summary统计和results明细。reviewCompleted=false表示仍有待复核或识别失败结果")
@PreAuthorize("@ss.hasPermi('inspection:result:report')")
@GetMapping("/report/{taskInstanceId}")
public AjaxResult report(@ApiParam(value = "巡检任务实例数据库ID", required = true)
@PathVariable String taskInstanceId)
{
AjaxResult result = AjaxResult.success();
result.put("summary", inspectionResultService.buildReportSummary(taskInstanceId));
InspectionResultQuery query = new InspectionResultQuery();
query.setTaskInstanceId(taskInstanceId);
result.put("results", inspectionResultService.selectResultList(query));
return result;
}
@ApiOperation(value = "导出巡检结果报表",
notes = "按查询条件导出Excel不传条件时导出全部巡检结果")
@PreAuthorize("@ss.hasPermi('inspection:result:export')")
@Log(title = "巡检结果", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response,
@ApiParam("导出筛选条件") InspectionResultQuery query)
{
List<InspectionResultVo> list = inspectionResultService.selectResultList(query);
ExcelUtil<InspectionResultVo> util = new ExcelUtil<>(InspectionResultVo.class);
util.exportExcel(response, list, "巡检结果数据");
}
}

View File

@ -0,0 +1,241 @@
package com.cmvr.web.controller.inspection;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import cmvr.msgs.Agv;
import com.cmvr.inspection.domain.vo.InspectionRobotVo;
import io.swagger.annotations.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.inspection.domain.InspectionRobot;
import com.cmvr.inspection.service.IInspectionRobotService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
/**
* 巡检机器人Controller
*
* @author cmvr-iot
* @since 2026-05-29
*/
@RestController
@RequestMapping("/inspection/robot")
@Api(tags = "智能巡检--机器人管理")
public class InspectionRobotController extends BaseController
{
@Autowired
private IInspectionRobotService inspectionRobotService;
/**
* 查询巡检机器人列表
*/
@ApiOperation("查询巡检机器人列表")
@PreAuthorize("@ss.hasPermi('inspection:robot:list')")
@GetMapping("/list")
public TableDataInfo list(InspectionRobot inspectionRobot)
{
startPage();
List<InspectionRobotVo> list = inspectionRobotService.selectInspectionRobotList(inspectionRobot);
return getDataTable(list);
}
/**
* 导出巡检机器人列表
*/
@ApiOperation("导出巡检机器人列表")
@PreAuthorize("@ss.hasPermi('inspection:robot:export')")
@Log(title = "巡检机器人", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, InspectionRobot inspectionRobot)
{
List<InspectionRobotVo> list = inspectionRobotService.selectInspectionRobotList(inspectionRobot);
ExcelUtil<InspectionRobotVo> util = new ExcelUtil<>(InspectionRobotVo.class);
util.exportExcel(response, list, "巡检机器人数据");
}
/**
* 获取巡检机器人详细信息
*/
@ApiOperation("获取巡检机器人详细信息")
@PreAuthorize("@ss.hasPermi('inspection:robot:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id)
{
return success(inspectionRobotService.selectInspectionRobotById(id));
}
/**
* 新增巡检机器人
*/
@ApiOperation("新增巡检机器人")
@PreAuthorize("@ss.hasPermi('inspection:robot:add')")
@Log(title = "巡检机器人", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody InspectionRobot inspectionRobot)
{
return toAjax(inspectionRobotService.insertInspectionRobot(inspectionRobot));
}
/**
* 修改巡检机器人
*/
@ApiOperation("修改巡检机器人")
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
@Log(title = "巡检机器人", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody InspectionRobot inspectionRobot)
{
return toAjax(inspectionRobotService.updateInspectionRobot(inspectionRobot));
}
/**
* 删除巡检机器人
*/
@ApiOperation("删除巡检机器人")
@PreAuthorize("@ss.hasPermi('inspection:robot:remove')")
@Log(title = "巡检机器人", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
return toAjax(inspectionRobotService.deleteInspectionRobotByIds(ids));
}
/**
* 获取机器人地图列表从AGV获取
*/
@ApiOperation("获取机器人地图列表")
@PreAuthorize("@ss.hasPermi('inspection:robot:query')")
@GetMapping("/{robotId}/maps")
public AjaxResult getRobotMapList(@PathVariable String robotId)
{
List<String> robotMapList = inspectionRobotService.getRobotMapList(robotId);
return success(robotMapList);
}
/**
* 绑定机器人地图
*/
@ApiOperation("绑定机器人地图")
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
@Log(title = "绑定机器人地图", businessType = BusinessType.UPDATE)
@PostMapping("/{robotId}/bind-map/{mapId}")
public AjaxResult bindRobotMap(@PathVariable String robotId,
@PathVariable String mapId)
{
return toAjax(inspectionRobotService.bindRobotMap(robotId, mapId));
}
/**
* 从机器人下载地图
*/
@ApiOperation("从机器人下载地图")
@PreAuthorize("@ss.hasPermi('inspection:robot:add')")
@Log(title = "从机器人下载地图", businessType = BusinessType.INSERT)
@GetMapping("/{robotId}/download-map")
public AjaxResult downloadMapFromRobot(
@PathVariable @ApiParam("机器人ID") String robotId,
@RequestParam(value = "mapName") @ApiParam("地图名称") String mapName
)
{
Object mapId = inspectionRobotService.downloadMapFromRobot(robotId, mapName);
return success(mapId);
}
/**
* 上传地图从源机器人下载到目标机器人
*/
@ApiOperation("上传地图到机器人")
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
@Log(title = "上传地图到机器人", businessType = BusinessType.OTHER)
@PostMapping("/{robotId}/upload-map-from-source")
public AjaxResult uploadMapFromSource(@PathVariable String robotId)
{
String result = inspectionRobotService.uploadMapFromSource(robotId);
return success(result);
}
/**
* 同步机器人状态
*/
@ApiOperation("同步机器人状态")
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
@Log(title = "同步机器人状态", businessType = BusinessType.UPDATE)
@PostMapping("/{robotId}/sync-status")
public AjaxResult syncRobotStatus(@PathVariable String robotId)
{
return success(inspectionRobotService.syncRobotStatus(robotId));
}
/**
* 获取机器人实时位置
*/
@ApiOperation("获取机器人实时位置")
@PreAuthorize("@ss.hasPermi('inspection:robot:query')")
@GetMapping("/{robotId}/location")
public AjaxResult getRobotRealtimeLocation(@PathVariable String robotId)
{
Agv.AgvPose2d location = inspectionRobotService.getRobotRealtimeLocation(robotId);
return success(location);
}
/**
* 导航到指定位置坐标
*/
@ApiOperation("导航到指定位置")
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
@Log(title = "导航到指定位置", businessType = BusinessType.OTHER)
@PostMapping("/{robotId}/navigate-to-position")
public AjaxResult navigateToPosition(
@PathVariable @ApiParam("机器人ID") String robotId,
@RequestParam @ApiParam("X坐标") Double x,
@RequestParam @ApiParam("Y坐标") Double y,
@RequestParam(required = false) @ApiParam("朝向角(弧度)") Double theta
)
{
inspectionRobotService.navigateToPosition(
robotId, x, y, theta
);
return success();
}
/**
* 开始建图
*/
@ApiOperation("开始建图")
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
@Log(title = "开始建图", businessType = BusinessType.OTHER)
@PostMapping("/{robotId}/start-mapping")
public AjaxResult startMapping(
@PathVariable @ApiParam("机器人ID") String robotId,
@RequestParam @ApiParam("建图维度0:未指定 1:2D 2:3D 3:2D+3D") int dimension,
@RequestParam(required = false) @ApiParam("地图名称(可选)") String mapName,
@RequestParam(defaultValue = "true") @ApiParam("是否实时建图") boolean realTime
)
{
String sessionId = inspectionRobotService.startMapping(robotId, dimension, mapName, realTime);
java.util.Map<String, Object> result = new java.util.HashMap<>();
result.put("sessionId", sessionId);
return success(result);
}
/**
* 停止建图
*/
@ApiOperation("停止建图")
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
@Log(title = "停止建图", businessType = BusinessType.OTHER)
@PostMapping("/{robotId}/stop-mapping")
public AjaxResult stopMapping(@PathVariable @ApiParam("机器人ID") String robotId)
{
inspectionRobotService.stopMapping(robotId);
return success();
}
}

View File

@ -0,0 +1,151 @@
package com.cmvr.web.controller.inspection;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.inspection.domain.InspectionTask;
import com.cmvr.inspection.domain.InspectionWaypoint;
import com.cmvr.inspection.domain.vo.InspectionTaskVo;
import com.cmvr.inspection.service.IInspectionTaskService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
/**
* 巡检任务Controller
*
* @author cmvr-iot
* @since 2026-05-29
*/
@RestController
@RequestMapping("/inspection/task")
@Api(tags = "智能巡检--任务管理")
public class InspectionTaskController extends BaseController
{
@Autowired
private IInspectionTaskService inspectionTaskService;
/**
* 查询巡检任务列表
*/
@ApiOperation("查询巡检任务列表")
@PreAuthorize("@ss.hasPermi('inspection:task:list')")
@GetMapping("/list")
public TableDataInfo list(InspectionTask inspectionTask)
{
startPage();
List<InspectionTaskVo> list = inspectionTaskService.selectInspectionTaskList(inspectionTask);
return getDataTable(list);
}
/**
* 导出巡检任务列表
*/
@ApiOperation("导出巡检任务列表")
@PreAuthorize("@ss.hasPermi('inspection:task:export')")
@Log(title = "巡检任务", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, InspectionTask inspectionTask)
{
List<InspectionTaskVo> list = inspectionTaskService.selectInspectionTaskList(inspectionTask);
ExcelUtil<InspectionTaskVo> util = new ExcelUtil<>(InspectionTaskVo.class);
util.exportExcel(response, list, "巡检任务数据");
}
/**
* 获取巡检任务详细信息
*/
@ApiOperation("获取巡检任务详细信息")
@PreAuthorize("@ss.hasPermi('inspection:task:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id)
{
return success(inspectionTaskService.selectInspectionTaskById(id));
}
/**
* 新增巡检任务
*/
@ApiOperation("新增巡检任务")
@PreAuthorize("@ss.hasPermi('inspection:task:add')")
@Log(title = "巡检任务", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody InspectionTask inspectionTask)
{
return toAjax(inspectionTaskService.insertInspectionTask(inspectionTask));
}
/**
* 修改巡检任务
*/
@ApiOperation("修改巡检任务")
@PreAuthorize("@ss.hasPermi('inspection:task:edit')")
@Log(title = "巡检任务", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody InspectionTask inspectionTask)
{
return toAjax(inspectionTaskService.updateInspectionTask(inspectionTask));
}
/**
* 删除巡检任务
*/
@ApiOperation("删除巡检任务")
@PreAuthorize("@ss.hasPermi('inspection:task:remove')")
@Log(title = "巡检任务", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
return toAjax(inspectionTaskService.deleteInspectionTaskByIds(ids));
}
/**
* 查询任务关联的点位列表
*/
@ApiOperation("查询任务关联的点位列表")
@PreAuthorize("@ss.hasPermi('inspection:task:query')")
@GetMapping("/{taskId}/waypoints")
public AjaxResult getWaypoints(@PathVariable("taskId") String taskId)
{
List<InspectionWaypoint> list = inspectionTaskService.selectWaypointsByTaskId(taskId);
return success(list);
}
/**
* 绑定点位到任务
*/
@ApiOperation("绑定点位到任务")
@PreAuthorize("@ss.hasPermi('inspection:task:edit')")
@Log(title = "巡检任务", businessType = BusinessType.UPDATE)
@PostMapping("/{taskId}/waypoints")
public AjaxResult bindWaypoints(@PathVariable("taskId") String taskId, @RequestBody String[] waypointIds)
{
return toAjax(inspectionTaskService.bindWaypoints(taskId, waypointIds));
}
/**
* 解绑任务的点位
*/
@ApiOperation("解绑任务的点位")
@PreAuthorize("@ss.hasPermi('inspection:task:edit')")
@Log(title = "巡检任务", businessType = BusinessType.UPDATE)
@DeleteMapping("/{taskId}/waypoints")
public AjaxResult unbindWaypoints(@PathVariable("taskId") String taskId)
{
return toAjax(inspectionTaskService.unbindWaypoints(taskId));
}
}

View File

@ -0,0 +1,164 @@
package com.cmvr.web.controller.inspection;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.cmvr.inspection.domain.dto.InspectionTaskInstanceQuery;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.inspection.domain.InspectionTaskInstance;
import com.cmvr.inspection.domain.vo.InspectionTaskInstanceVo;
import com.cmvr.inspection.service.IInspectionTaskInstanceService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
/**
* 巡检任务执行实例Controller
*
* @author cmvr-iot
* @since 2026-06-01
*/
@RestController
@RequestMapping("/inspection/taskInstance")
@Api(tags = "智能巡检--任务执行实例管理")
public class InspectionTaskInstanceController extends BaseController
{
@Autowired
private IInspectionTaskInstanceService inspectionTaskInstanceService;
/**
* 查询巡检任务执行实例列表
*/
@ApiOperation("查询巡检任务执行实例列表")
@PreAuthorize("@ss.hasPermi('inspection:taskInstance:list')")
@GetMapping("/list")
public TableDataInfo list(InspectionTaskInstanceQuery inspectionTaskInstanceQuery)
{
startPage();
List<InspectionTaskInstanceVo> list = inspectionTaskInstanceService.selectInspectionTaskInstanceList(inspectionTaskInstanceQuery);
return getDataTable(list);
}
/**
* 导出巡检任务执行实例列表
*/
@ApiOperation("导出巡检任务执行实例列表")
@PreAuthorize("@ss.hasPermi('inspection:taskInstance:export')")
@Log(title = "巡检任务执行实例", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, InspectionTaskInstanceQuery inspectionTaskInstanceQuery)
{
List<InspectionTaskInstanceVo> list = inspectionTaskInstanceService.selectInspectionTaskInstanceList(inspectionTaskInstanceQuery);
ExcelUtil<InspectionTaskInstanceVo> util = new ExcelUtil<>(InspectionTaskInstanceVo.class);
util.exportExcel(response, list, "巡检任务执行实例数据");
}
/**
* 获取巡检任务执行实例详细信息
*/
@ApiOperation("获取巡检任务执行实例详细信息")
@PreAuthorize("@ss.hasPermi('inspection:taskInstance:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id)
{
return success(inspectionTaskInstanceService.selectInspectionTaskInstanceVoById(id));
}
/**
* 新增巡检任务执行实例
*/
@ApiOperation("新增巡检任务执行实例")
@PreAuthorize("@ss.hasPermi('inspection:taskInstance:add')")
@Log(title = "巡检任务执行实例", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody InspectionTaskInstance inspectionTaskInstance)
{
return toAjax(inspectionTaskInstanceService.insertInspectionTaskInstance(inspectionTaskInstance));
}
/**
* 修改巡检任务执行实例
*/
@ApiOperation("修改巡检任务执行实例")
@PreAuthorize("@ss.hasPermi('inspection:taskInstance:edit')")
@Log(title = "巡检任务执行实例", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody InspectionTaskInstance inspectionTaskInstance)
{
return toAjax(inspectionTaskInstanceService.updateInspectionTaskInstance(inspectionTaskInstance));
}
/**
* 删除巡检任务执行实例
*/
@ApiOperation("删除巡检任务执行实例")
@PreAuthorize("@ss.hasPermi('inspection:taskInstance:remove')")
@Log(title = "巡检任务执行实例", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
return toAjax(inspectionTaskInstanceService.deleteInspectionTaskInstanceByIds(ids));
}
/**
* 开始执行任务实例
*/
@ApiOperation("开始执行任务实例")
@PreAuthorize("@ss.hasPermi('inspection:taskInstance:edit')")
@Log(title = "巡检任务执行实例", businessType = BusinessType.UPDATE)
@PutMapping("/start/{id}")
public AjaxResult start(@PathVariable("id") String id)
{
return toAjax(inspectionTaskInstanceService.startInstance(id));
}
/**
* 暂停任务实例
*/
@ApiOperation("暂停任务实例")
@PreAuthorize("@ss.hasPermi('inspection:taskInstance:edit')")
@Log(title = "巡检任务执行实例", businessType = BusinessType.UPDATE)
@PutMapping("/pause/{id}")
public AjaxResult pause(@PathVariable("id") String id)
{
return toAjax(inspectionTaskInstanceService.pauseInstance(id));
}
/**
* 终止任务实例
*/
@ApiOperation("终止任务实例")
@PreAuthorize("@ss.hasPermi('inspection:taskInstance:edit')")
@Log(title = "巡检任务执行实例", businessType = BusinessType.UPDATE)
@PutMapping("/stop/{id}")
public AjaxResult stop(@PathVariable("id") String id)
{
return toAjax(inspectionTaskInstanceService.stopInstance(id));
}
/**
* 恢复任务实例
*/
@ApiOperation("恢复任务实例")
@PreAuthorize("@ss.hasPermi('inspection:taskInstance:edit')")
@Log(title = "巡检任务执行实例", businessType = BusinessType.UPDATE)
@PutMapping("/resume/{id}")
public AjaxResult resume(@PathVariable("id") String id)
{
return toAjax(inspectionTaskInstanceService.resumeInstance(id));
}
}

View File

@ -0,0 +1,84 @@
package com.cmvr.web.controller.inspection;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.inspection.domain.InspectionTaskLog;
import com.cmvr.inspection.service.IInspectionTaskLogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 巡检任务执行日志Controller
*
* @author cmvr-iot
* @since 2026-06-05
*/
@Api(tags = "智能巡检-巡检任务执行日志管理")
@RestController
@RequestMapping("/inspection/taskLog")
public class InspectionTaskLogController extends BaseController
{
@Autowired
private IInspectionTaskLogService inspectionTaskLogService;
/**
* 查询巡检任务执行日志列表
*/
@ApiOperation("查询巡检任务执行日志列表")
@GetMapping("/list")
public TableDataInfo list(@ApiParam("任务实例ID") @RequestParam String taskInstanceId) {
List<InspectionTaskLog> list = inspectionTaskLogService.selectInspectionTaskLogList(taskInstanceId);
return getDataTable(list);
}
/**
* 获取巡检任务执行日志详细信息
*/
@ApiOperation("获取巡检任务执行日志详细信息")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@ApiParam("日志ID") @PathVariable("id") String id) {
return success(inspectionTaskLogService.getById(id));
}
/**
* 新增巡检任务执行日志
*/
@ApiOperation("新增巡检任务执行日志")
@PostMapping
public AjaxResult add(@RequestBody InspectionTaskLog inspectionTaskLog) {
return toAjax(inspectionTaskLogService.insertInspectionTaskLog(inspectionTaskLog));
}
/**
* 批量新增巡检任务执行日志
*/
@ApiOperation("批量新增巡检任务执行日志")
@PostMapping("/batch")
public AjaxResult batchAdd(@RequestBody List<InspectionTaskLog> logList) {
return toAjax(inspectionTaskLogService.batchInsertInspectionTaskLog(logList));
}
/**
* 修改巡检任务执行日志
*/
@ApiOperation("修改巡检任务执行日志")
@PutMapping
public AjaxResult edit(@RequestBody InspectionTaskLog inspectionTaskLog) {
return toAjax(inspectionTaskLogService.updateById(inspectionTaskLog));
}
/**
* 删除巡检任务执行日志
*/
@ApiOperation("删除巡检任务执行日志")
@DeleteMapping("/{ids}")
public AjaxResult remove(@ApiParam("日志ID数组") @PathVariable String[] ids) {
return toAjax(inspectionTaskLogService.removeByIds(java.util.Arrays.asList(ids)));
}
}

View File

@ -0,0 +1,115 @@
package com.cmvr.web.controller.inspection;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.inspection.domain.InspectionWaypoint;
import com.cmvr.inspection.domain.vo.InspectionWaypointVo;
import com.cmvr.inspection.service.IInspectionWaypointService;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.common.core.page.TableDataInfo;
/**
* 巡检点位Controller
*
* @author cmvr-iot
* @since 2026-05-29
*/
@RestController
@RequestMapping("/inspection/waypoint")
@Api(tags = "智能巡检--点位管理")
public class InspectionWaypointController extends BaseController
{
@Autowired
private IInspectionWaypointService inspectionWaypointService;
/**
* 查询巡检点位列表
*/
@ApiOperation("查询巡检点位列表")
@PreAuthorize("@ss.hasPermi('inspection:waypoint:list')")
@GetMapping("/list")
public TableDataInfo list(InspectionWaypoint inspectionWaypoint)
{
startPage();
List<InspectionWaypointVo> list = inspectionWaypointService.selectInspectionWaypointList(inspectionWaypoint);
return getDataTable(list);
}
/**
* 导出巡检点位列表
*/
@ApiOperation("导出巡检点位列表")
@PreAuthorize("@ss.hasPermi('inspection:waypoint:export')")
@Log(title = "巡检点位", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, InspectionWaypoint inspectionWaypoint)
{
List<InspectionWaypointVo> list = inspectionWaypointService.selectInspectionWaypointList(inspectionWaypoint);
ExcelUtil<InspectionWaypointVo> util = new ExcelUtil<>(InspectionWaypointVo.class);
util.exportExcel(response, list, "巡检点位数据");
}
/**
* 获取巡检点位详细信息
*/
@ApiOperation("获取巡检点位详细信息")
@PreAuthorize("@ss.hasPermi('inspection:waypoint:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id)
{
return success(inspectionWaypointService.selectInspectionWaypointById(id));
}
/**
* 新增巡检点位
*/
@ApiOperation("新增巡检点位")
@PreAuthorize("@ss.hasPermi('inspection:waypoint:add')")
@Log(title = "巡检点位", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody InspectionWaypoint inspectionWaypoint)
{
return toAjax(inspectionWaypointService.insertInspectionWaypoint(inspectionWaypoint));
}
/**
* 修改巡检点位
*/
@ApiOperation("修改巡检点位")
@PreAuthorize("@ss.hasPermi('inspection:waypoint:edit')")
@Log(title = "巡检点位", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody InspectionWaypoint inspectionWaypoint)
{
return toAjax(inspectionWaypointService.updateInspectionWaypoint(inspectionWaypoint));
}
/**
* 删除巡检点位
*/
@ApiOperation("删除巡检点位")
@PreAuthorize("@ss.hasPermi('inspection:waypoint:remove')")
@Log(title = "巡检点位", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
return toAjax(inspectionWaypointService.deleteInspectionWaypointByIds(ids));
}
}

View File

@ -0,0 +1,121 @@
package com.cmvr.web.controller.monitor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.constant.CacheConstants;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.utils.StringUtils;
import com.cmvr.system.domain.SysCache;
/**
* 缓存监控
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/monitor/cache")
public class CacheController
{
@Autowired
private RedisTemplate<String, String> redisTemplate;
private final static List<SysCache> caches = new ArrayList<SysCache>();
{
caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息"));
caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息"));
caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典"));
caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码"));
caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交"));
caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理"));
caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数"));
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping()
public AjaxResult getInfo() throws Exception
{
Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info());
Properties commandStats = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info("commandstats"));
Object dbSize = redisTemplate.execute((RedisCallback<Object>) connection -> connection.dbSize());
Map<String, Object> result = new HashMap<>(3);
result.put("info", info);
result.put("dbSize", dbSize);
List<Map<String, String>> pieList = new ArrayList<>();
commandStats.stringPropertyNames().forEach(key -> {
Map<String, String> data = new HashMap<>(2);
String property = commandStats.getProperty(key);
data.put("name", StringUtils.removeStart(key, "cmdstat_"));
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
pieList.add(data);
});
result.put("commandStats", pieList);
return AjaxResult.success(result);
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getNames")
public AjaxResult cache()
{
return AjaxResult.success(caches);
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getKeys/{cacheName}")
public AjaxResult getCacheKeys(@PathVariable String cacheName)
{
Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
return AjaxResult.success(new TreeSet<>(cacheKeys));
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getValue/{cacheName}/{cacheKey}")
public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey)
{
String cacheValue = redisTemplate.opsForValue().get(cacheKey);
SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue);
return AjaxResult.success(sysCache);
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@DeleteMapping("/clearCacheName/{cacheName}")
public AjaxResult clearCacheName(@PathVariable String cacheName)
{
Collection<String> cacheKeys = redisTemplate.keys(cacheName + "*");
redisTemplate.delete(cacheKeys);
return AjaxResult.success();
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@DeleteMapping("/clearCacheKey/{cacheKey}")
public AjaxResult clearCacheKey(@PathVariable String cacheKey)
{
redisTemplate.delete(cacheKey);
return AjaxResult.success();
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@DeleteMapping("/clearCacheAll")
public AjaxResult clearCacheAll()
{
Collection<String> cacheKeys = redisTemplate.keys("*");
redisTemplate.delete(cacheKeys);
return AjaxResult.success();
}
}

View File

@ -0,0 +1,27 @@
package com.cmvr.web.controller.monitor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.framework.web.domain.Server;
/**
* 服务器监控
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/monitor/server")
public class ServerController
{
@PreAuthorize("@ss.hasPermi('monitor:server:list')")
@GetMapping()
public AjaxResult getInfo() throws Exception
{
Server server = new Server();
server.copyTo();
return AjaxResult.success(server);
}
}

View File

@ -0,0 +1,82 @@
package com.cmvr.web.controller.monitor;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.framework.web.service.SysPasswordService;
import com.cmvr.system.domain.SysLogininfor;
import com.cmvr.system.service.ISysLogininforService;
/**
* 系统访问记录
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/monitor/logininfor")
public class SysLogininforController extends BaseController
{
@Autowired
private ISysLogininforService logininforService;
@Autowired
private SysPasswordService passwordService;
@PreAuthorize("@ss.hasPermi('monitor:logininfor:list')")
@GetMapping("/list")
public TableDataInfo list(SysLogininfor logininfor)
{
startPage();
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
return getDataTable(list);
}
@Log(title = "登录日志", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysLogininfor logininfor)
{
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
util.exportExcel(response, list, "登录日志");
}
@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
@Log(title = "登录日志", businessType = BusinessType.DELETE)
@DeleteMapping("/{infoIds}")
public AjaxResult remove(@PathVariable Long[] infoIds)
{
return toAjax(logininforService.deleteLogininforByIds(infoIds));
}
@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
@Log(title = "登录日志", businessType = BusinessType.CLEAN)
@DeleteMapping("/clean")
public AjaxResult clean()
{
logininforService.cleanLogininfor();
return success();
}
@PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')")
@Log(title = "账户解锁", businessType = BusinessType.OTHER)
@GetMapping("/unlock/{userName}")
public AjaxResult unlock(@PathVariable("userName") String userName)
{
passwordService.clearLoginRecordCache(userName);
return success();
}
}

View File

@ -0,0 +1,69 @@
package com.cmvr.web.controller.monitor;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.system.domain.SysOperLog;
import com.cmvr.system.service.ISysOperLogService;
/**
* 操作日志记录
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/monitor/operlog")
public class SysOperlogController extends BaseController
{
@Autowired
private ISysOperLogService operLogService;
@PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
@GetMapping("/list")
public TableDataInfo list(SysOperLog operLog)
{
startPage();
List<SysOperLog> list = operLogService.selectOperLogList(operLog);
return getDataTable(list);
}
@Log(title = "操作日志", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysOperLog operLog)
{
List<SysOperLog> list = operLogService.selectOperLogList(operLog);
ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
util.exportExcel(response, list, "操作日志");
}
@Log(title = "操作日志", businessType = BusinessType.DELETE)
@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
@DeleteMapping("/{operIds}")
public AjaxResult remove(@PathVariable Long[] operIds)
{
return toAjax(operLogService.deleteOperLogByIds(operIds));
}
@Log(title = "操作日志", businessType = BusinessType.CLEAN)
@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
@DeleteMapping("/clean")
public AjaxResult clean()
{
operLogService.cleanOperLog();
return success();
}
}

View File

@ -0,0 +1,83 @@
package com.cmvr.web.controller.monitor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.constant.CacheConstants;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.domain.model.LoginUser;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.core.redis.RedisCache;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.StringUtils;
import com.cmvr.system.domain.SysUserOnline;
import com.cmvr.system.service.ISysUserOnlineService;
/**
* 在线用户监控
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/monitor/online")
public class SysUserOnlineController extends BaseController
{
@Autowired
private ISysUserOnlineService userOnlineService;
@Autowired
private RedisCache redisCache;
@PreAuthorize("@ss.hasPermi('monitor:online:list')")
@GetMapping("/list")
public TableDataInfo list(String ipaddr, String userName)
{
Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
for (String key : keys)
{
LoginUser user = redisCache.getCacheObject(key);
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
{
userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
}
else if (StringUtils.isNotEmpty(ipaddr))
{
userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
}
else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser()))
{
userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
}
else
{
userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
}
}
Collections.reverse(userOnlineList);
userOnlineList.removeAll(Collections.singleton(null));
return getDataTable(userOnlineList);
}
/**
* 强退用户
*/
@PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')")
@Log(title = "在线用户", businessType = BusinessType.FORCE)
@DeleteMapping("/{tokenId}")
public AjaxResult forceLogout(@PathVariable String tokenId)
{
redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
return success();
}
}

View File

@ -0,0 +1,95 @@
package com.cmvr.web.controller.show;
import cn.hutool.core.util.StrUtil;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.llm.model.CallAgentVO;
import com.cmvr.llm.model.CallAgentAdvancedVO;
import com.cmvr.llm.model.CallTTSAdvancedVO;
import com.cmvr.llm.model.CallTTSVO;
import com.cmvr.llm.service.ShowIntelligentCockpitService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.Valid;
import java.io.IOException;
@Api(tags = "演示--智能座舱")
@RestController
@RequestMapping("/show")
@RequiredArgsConstructor
public class ShowIntelligentCockpitController extends BaseController {
private final ShowIntelligentCockpitService showIntelligentCockpitService;
// ----------------------------- 语音合成 -----------------------------
@Log(title = "演示-智能座舱-创建音色", businessType = BusinessType.OTHER)
@ApiOperation("创建音色")
@PostMapping("/tts/create")
public AjaxResult create(@RequestPart(value = "file") MultipartFile file) throws IOException {
return success(showIntelligentCockpitService.createTimbre(file));
}
@ApiOperation("查询音色")
@GetMapping("/tts/query")
public AjaxResult query() {
return success(showIntelligentCockpitService.queryTimbre());
}
@Log(title = "演示-智能座舱-生成语料", businessType = BusinessType.OTHER)
@ApiOperation("生成语料")
@PostMapping("/tts/corpus")
public AjaxResult corpus(@Valid @RequestBody CallAgentVO callAgentVO) {
callAgentVO.setConvertWords(StrUtil.trim(callAgentVO.getConvertWords()));
return success(showIntelligentCockpitService.genCorpus(callAgentVO));
}
@Log(title = "演示-智能座舱-语音合成", businessType = BusinessType.OTHER)
@ApiOperation("语音合成")
@PostMapping("/tts/synthesize")
public ResponseEntity<byte[]> synthesize(@Valid @RequestBody CallTTSVO callTTSVO) {
callTTSVO.setText(StrUtil.trim(callTTSVO.getText()));
return showIntelligentCockpitService.synthesizeAudio(callTTSVO);
}
@Log(title = "演示-智能座舱-生成语料-增强", businessType = BusinessType.OTHER)
@ApiOperation("生成语料-增强")
@PostMapping("/tts/corpus/advanced")
public AjaxResult corpusAdvanced(@Valid @RequestBody CallAgentAdvancedVO callAgentAdvancedVO) {
callAgentAdvancedVO.setConvertWords(StrUtil.trim(callAgentAdvancedVO.getConvertWords()));
return success(showIntelligentCockpitService.genCorpusAdvanced(callAgentAdvancedVO));
}
@Log(title = "演示-智能座舱-语音合成-增强", businessType = BusinessType.OTHER)
@ApiOperation("语音合成-增强")
@PostMapping("/tts/synthesize/advanced")
public ResponseEntity<byte[]> synthesizeAdvanced(@Valid @RequestBody CallTTSAdvancedVO callTTSAdvancedVO) {
callTTSAdvancedVO.setText(StrUtil.trim(callTTSAdvancedVO.getText()));
return showIntelligentCockpitService.synthesizeAudioAdvanced(callTTSAdvancedVO);
}
// ----------------------------- 触控交互 -----------------------------
@Log(title = "演示-智能座舱-触控坐标", businessType = BusinessType.OTHER)
@ApiOperation("触控坐标")
@PostMapping("/touch/coordinates")
public AjaxResult coordinates(
@RequestPart(value = "image") MultipartFile image,
@RequestParam("words") String words
) throws Exception {
return success(showIntelligentCockpitService.getCoordinates(image.getBytes(), words));
}
}

View File

@ -0,0 +1,133 @@
package com.cmvr.web.controller.system;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.system.domain.SysConfig;
import com.cmvr.system.service.ISysConfigService;
/**
* 参数配置 信息操作处理
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/system/config")
public class SysConfigController extends BaseController
{
@Autowired
private ISysConfigService configService;
/**
* 获取参数配置列表
*/
@PreAuthorize("@ss.hasPermi('system:config:list')")
@GetMapping("/list")
public TableDataInfo list(SysConfig config)
{
startPage();
List<SysConfig> list = configService.selectConfigList(config);
return getDataTable(list);
}
@Log(title = "参数管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:config:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysConfig config)
{
List<SysConfig> list = configService.selectConfigList(config);
ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
util.exportExcel(response, list, "参数数据");
}
/**
* 根据参数编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:config:query')")
@GetMapping(value = "/{configId}")
public AjaxResult getInfo(@PathVariable Long configId)
{
return success(configService.selectConfigById(configId));
}
/**
* 根据参数键名查询参数值
*/
@GetMapping(value = "/configKey/{configKey}")
public AjaxResult getConfigKey(@PathVariable String configKey)
{
return success(configService.selectConfigByKey(configKey));
}
/**
* 新增参数配置
*/
@PreAuthorize("@ss.hasPermi('system:config:add')")
@Log(title = "参数管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysConfig config)
{
if (!configService.checkConfigKeyUnique(config))
{
return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
config.setCreateBy(getUsername());
return toAjax(configService.insertConfig(config));
}
/**
* 修改参数配置
*/
@PreAuthorize("@ss.hasPermi('system:config:edit')")
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysConfig config)
{
if (!configService.checkConfigKeyUnique(config))
{
return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
config.setUpdateBy(getUsername());
return toAjax(configService.updateConfig(config));
}
/**
* 删除参数配置
*/
@PreAuthorize("@ss.hasPermi('system:config:remove')")
@Log(title = "参数管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{configIds}")
public AjaxResult remove(@PathVariable Long[] configIds)
{
configService.deleteConfigByIds(configIds);
return success();
}
/**
* 刷新参数缓存
*/
@PreAuthorize("@ss.hasPermi('system:config:remove')")
@Log(title = "参数管理", businessType = BusinessType.CLEAN)
@DeleteMapping("/refreshCache")
public AjaxResult refreshCache()
{
configService.resetConfigCache();
return success();
}
}

View File

@ -0,0 +1,132 @@
package com.cmvr.web.controller.system;
import java.util.List;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.constant.UserConstants;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.domain.entity.SysDept;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.StringUtils;
import com.cmvr.system.service.ISysDeptService;
/**
* 部门信息
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/system/dept")
public class SysDeptController extends BaseController
{
@Autowired
private ISysDeptService deptService;
/**
* 获取部门列表
*/
@PreAuthorize("@ss.hasPermi('system:dept:list')")
@GetMapping("/list")
public AjaxResult list(SysDept dept)
{
List<SysDept> depts = deptService.selectDeptList(dept);
return success(depts);
}
/**
* 查询部门列表排除节点
*/
@PreAuthorize("@ss.hasPermi('system:dept:list')")
@GetMapping("/list/exclude/{deptId}")
public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId)
{
List<SysDept> depts = deptService.selectDeptList(new SysDept());
depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""));
return success(depts);
}
/**
* 根据部门编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:dept:query')")
@GetMapping(value = "/{deptId}")
public AjaxResult getInfo(@PathVariable Long deptId)
{
deptService.checkDeptDataScope(deptId);
return success(deptService.selectDeptById(deptId));
}
/**
* 新增部门
*/
@PreAuthorize("@ss.hasPermi('system:dept:add')")
@Log(title = "部门管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysDept dept)
{
if (!deptService.checkDeptNameUnique(dept))
{
return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
}
dept.setCreateBy(getUsername());
return toAjax(deptService.insertDept(dept));
}
/**
* 修改部门
*/
@PreAuthorize("@ss.hasPermi('system:dept:edit')")
@Log(title = "部门管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysDept dept)
{
Long deptId = dept.getDeptId();
deptService.checkDeptDataScope(deptId);
if (!deptService.checkDeptNameUnique(dept))
{
return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
}
else if (dept.getParentId().equals(deptId))
{
return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
}
else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
{
return error("该部门包含未停用的子部门!");
}
dept.setUpdateBy(getUsername());
return toAjax(deptService.updateDept(dept));
}
/**
* 删除部门
*/
@PreAuthorize("@ss.hasPermi('system:dept:remove')")
@Log(title = "部门管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{deptId}")
public AjaxResult remove(@PathVariable Long deptId)
{
if (deptService.hasChildByDeptId(deptId))
{
return warn("存在下级部门,不允许删除");
}
if (deptService.checkDeptExistUser(deptId))
{
return warn("部门存在用户,不允许删除");
}
deptService.checkDeptDataScope(deptId);
return toAjax(deptService.deleteDeptById(deptId));
}
}

View File

@ -0,0 +1,121 @@
package com.cmvr.web.controller.system;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.domain.entity.SysDictData;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.StringUtils;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.system.service.ISysDictDataService;
import com.cmvr.system.service.ISysDictTypeService;
/**
* 数据字典信息
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/system/dict/data")
public class SysDictDataController extends BaseController
{
@Autowired
private ISysDictDataService dictDataService;
@Autowired
private ISysDictTypeService dictTypeService;
@PreAuthorize("@ss.hasPermi('system:dict:list')")
@GetMapping("/list")
public TableDataInfo list(SysDictData dictData)
{
startPage();
List<SysDictData> list = dictDataService.selectDictDataList(dictData);
return getDataTable(list);
}
@Log(title = "字典数据", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:dict:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysDictData dictData)
{
List<SysDictData> list = dictDataService.selectDictDataList(dictData);
ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class);
util.exportExcel(response, list, "字典数据");
}
/**
* 查询字典数据详细
*/
@PreAuthorize("@ss.hasPermi('system:dict:query')")
@GetMapping(value = "/{dictCode}")
public AjaxResult getInfo(@PathVariable Long dictCode)
{
return success(dictDataService.selectDictDataById(dictCode));
}
/**
* 根据字典类型查询字典数据信息
*/
@GetMapping(value = "/type/{dictType}")
public AjaxResult dictType(@PathVariable String dictType)
{
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
if (StringUtils.isNull(data))
{
data = new ArrayList<SysDictData>();
}
return success(data);
}
/**
* 新增字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:add')")
@Log(title = "字典数据", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysDictData dict)
{
dict.setCreateBy(getUsername());
return toAjax(dictDataService.insertDictData(dict));
}
/**
* 修改保存字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:edit')")
@Log(title = "字典数据", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysDictData dict)
{
dict.setUpdateBy(getUsername());
return toAjax(dictDataService.updateDictData(dict));
}
/**
* 删除字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictCodes}")
public AjaxResult remove(@PathVariable Long[] dictCodes)
{
dictDataService.deleteDictDataByIds(dictCodes);
return success();
}
}

View File

@ -0,0 +1,131 @@
package com.cmvr.web.controller.system;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.domain.entity.SysDictType;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.system.service.ISysDictTypeService;
/**
* 数据字典信息
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/system/dict/type")
public class SysDictTypeController extends BaseController
{
@Autowired
private ISysDictTypeService dictTypeService;
@PreAuthorize("@ss.hasPermi('system:dict:list')")
@GetMapping("/list")
public TableDataInfo list(SysDictType dictType)
{
startPage();
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
return getDataTable(list);
}
@Log(title = "字典类型", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:dict:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysDictType dictType)
{
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
ExcelUtil<SysDictType> util = new ExcelUtil<SysDictType>(SysDictType.class);
util.exportExcel(response, list, "字典类型");
}
/**
* 查询字典类型详细
*/
@PreAuthorize("@ss.hasPermi('system:dict:query')")
@GetMapping(value = "/{dictId}")
public AjaxResult getInfo(@PathVariable Long dictId)
{
return success(dictTypeService.selectDictTypeById(dictId));
}
/**
* 新增字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:add')")
@Log(title = "字典类型", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysDictType dict)
{
if (!dictTypeService.checkDictTypeUnique(dict))
{
return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setCreateBy(getUsername());
return toAjax(dictTypeService.insertDictType(dict));
}
/**
* 修改字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:edit')")
@Log(title = "字典类型", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysDictType dict)
{
if (!dictTypeService.checkDictTypeUnique(dict))
{
return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setUpdateBy(getUsername());
return toAjax(dictTypeService.updateDictType(dict));
}
/**
* 删除字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictIds}")
public AjaxResult remove(@PathVariable Long[] dictIds)
{
dictTypeService.deleteDictTypeByIds(dictIds);
return success();
}
/**
* 刷新字典缓存
*/
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
@Log(title = "字典类型", businessType = BusinessType.CLEAN)
@DeleteMapping("/refreshCache")
public AjaxResult refreshCache()
{
dictTypeService.resetDictCache();
return success();
}
/**
* 获取字典选择框列表
*/
@GetMapping("/optionselect")
public AjaxResult optionselect()
{
List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll();
return success(dictTypes);
}
}

View File

@ -0,0 +1,51 @@
package com.cmvr.web.controller.system;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.domain.entity.SysFileInfo;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.system.service.ISysFileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@Api(tags = "通用--文件管理")
@RestController
@RequestMapping("/system/file")
@RequiredArgsConstructor
public class SysFileInfoController extends BaseController {
private final ISysFileService sysFileService;
@ApiOperation("查询文件")
@GetMapping("/list")
public TableDataInfo query(SysFileInfo sysFileInfo) {
startPage();
List<SysFileInfo> list = sysFileService.selectFileList(sysFileInfo);
return getDataTable(list);
}
@ApiOperation(value = "上传文件上传后返回文件URL", notes = "0:其他、1:普通文件、2:图片、3:音频、4:视频")
@Log(title = "文件管理", businessType = BusinessType.INSERT)
@PostMapping("/upload")
public AjaxResult upload(
@RequestParam("fileType") Integer fileType,
@RequestPart("file") MultipartFile file
) {
return AjaxResult.success(sysFileService.uploadFile(file, fileType));
}
@ApiOperation("删除文件")
@Log(title = "文件管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{groupIds}")
public AjaxResult remove(@PathVariable Long[] groupIds) {
return toAjax(sysFileService.deleteFileByIds(groupIds));
}
}

View File

@ -0,0 +1,64 @@
package com.cmvr.web.controller.system;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.domain.entity.SysGroup;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.system.service.ISysGroupService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Api(tags = "通用--分组配置")
@RestController
@RequestMapping("/system/group")
@RequiredArgsConstructor
public class SysGroupController extends BaseController {
private final ISysGroupService sysGroupService;
@ApiOperation("查询通用分组配置列表")
@PreAuthorize("@ss.hasPermi('system:group:list')")
@GetMapping("/list")
public TableDataInfo list(SysGroup sysGroup) {
startPage();
List<SysGroup> list = sysGroupService.selectSysGroupList(sysGroup);
return getDataTable(list);
}
@ApiOperation("获取通用分组配置详细信息")
@PreAuthorize("@ss.hasPermi('system:group:query')")
@GetMapping(value = "/{groupId}")
public AjaxResult getInfo(@PathVariable("groupId") Long groupId) {
return success(sysGroupService.selectSysGroupByGroupId(groupId));
}
@ApiOperation("新增通用分组配置")
@PreAuthorize("@ss.hasPermi('system:group:add')")
@Log(title = "通用分组配置", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SysGroup sysGroup) {
return toAjax(sysGroupService.insertSysGroup(sysGroup));
}
@ApiOperation("修改通用分组配置")
@PreAuthorize("@ss.hasPermi('system:group:edit')")
@Log(title = "通用分组配置", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SysGroup sysGroup) {
return toAjax(sysGroupService.updateSysGroup(sysGroup));
}
@ApiOperation("删除通用分组配置")
@PreAuthorize("@ss.hasPermi('system:group:remove')")
@Log(title = "通用分组配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{groupIds}")
public AjaxResult remove(@PathVariable Long[] groupIds) {
return toAjax(sysGroupService.deleteSysGroupByGroupIds(groupIds));
}
}

View File

@ -0,0 +1,29 @@
package com.cmvr.web.controller.system;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.config.CmvrIotConfig;
import com.cmvr.common.utils.StringUtils;
/**
* 首页
*
* @author cmvr-iot
*/
@RestController
public class SysIndexController
{
/** 系统基础配置 */
@Autowired
private CmvrIotConfig cmvrIotConfig;
/**
* 访问首页提示语
*/
@RequestMapping("/")
public String index()
{
return StringUtils.format("欢迎使用{}后台管理框架当前版本v{},请通过前端地址访问。", cmvrIotConfig.getName(), cmvrIotConfig.getVersion());
}
}

View File

@ -0,0 +1,102 @@
package com.cmvr.web.controller.system;
import java.util.List;
import java.util.Set;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.constant.Constants;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.domain.entity.SysMenu;
import com.cmvr.common.core.domain.entity.SysUser;
import com.cmvr.common.core.domain.model.LoginBody;
import com.cmvr.common.core.domain.model.LoginUser;
import com.cmvr.common.utils.SecurityUtils;
import com.cmvr.framework.web.service.SysLoginService;
import com.cmvr.framework.web.service.SysPermissionService;
import com.cmvr.framework.web.service.TokenService;
import com.cmvr.system.service.ISysMenuService;
/**
* 登录验证
*
* @author cmvr-iot
*/
@Api(tags = "通用--登录验证")
@RestController
public class SysLoginController
{
@Autowired
private SysLoginService loginService;
@Autowired
private ISysMenuService menuService;
@Autowired
private SysPermissionService permissionService;
@Autowired
private TokenService tokenService;
/**
* 登录方法
*
* @param loginBody 登录信息
* @return 结果
*/
@ApiOperation("登录")
@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody)
{
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
loginBody.getUuid());
ajax.put(Constants.TOKEN, token);
return ajax;
}
/**
* 获取用户信息
*
* @return 用户信息
*/
@GetMapping("getInfo")
public AjaxResult getInfo()
{
LoginUser loginUser = SecurityUtils.getLoginUser();
SysUser user = loginUser.getUser();
// 角色集合
Set<String> roles = permissionService.getRolePermission(user);
// 权限集合
Set<String> permissions = permissionService.getMenuPermission(user);
if (!loginUser.getPermissions().equals(permissions))
{
loginUser.setPermissions(permissions);
tokenService.refreshToken(loginUser);
}
AjaxResult ajax = AjaxResult.success();
ajax.put("user", user);
ajax.put("roles", roles);
ajax.put("permissions", permissions);
return ajax;
}
/**
* 获取路由信息
*
* @return 路由信息
*/
@GetMapping("getRouters")
public AjaxResult getRouters()
{
Long userId = SecurityUtils.getUserId();
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
return AjaxResult.success(menuService.buildMenus(menus));
}
}

View File

@ -0,0 +1,142 @@
package com.cmvr.web.controller.system;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.constant.UserConstants;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.domain.entity.SysMenu;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.StringUtils;
import com.cmvr.system.service.ISysMenuService;
/**
* 菜单信息
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/system/menu")
public class SysMenuController extends BaseController
{
@Autowired
private ISysMenuService menuService;
/**
* 获取菜单列表
*/
@PreAuthorize("@ss.hasPermi('system:menu:list')")
@GetMapping("/list")
public AjaxResult list(SysMenu menu)
{
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
return success(menus);
}
/**
* 根据菜单编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:menu:query')")
@GetMapping(value = "/{menuId}")
public AjaxResult getInfo(@PathVariable Long menuId)
{
return success(menuService.selectMenuById(menuId));
}
/**
* 获取菜单下拉树列表
*/
@GetMapping("/treeselect")
public AjaxResult treeselect(SysMenu menu)
{
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
return success(menuService.buildMenuTreeSelect(menus));
}
/**
* 加载对应角色菜单列表树
*/
@GetMapping(value = "/roleMenuTreeselect/{roleId}")
public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId)
{
List<SysMenu> menus = menuService.selectMenuList(getUserId());
AjaxResult ajax = AjaxResult.success();
ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
ajax.put("menus", menuService.buildMenuTreeSelect(menus));
return ajax;
}
/**
* 新增菜单
*/
@PreAuthorize("@ss.hasPermi('system:menu:add')")
@Log(title = "菜单管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysMenu menu)
{
if (!menuService.checkMenuNameUnique(menu))
{
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
{
return error("新增菜单'" + menu.getMenuName() + "'失败地址必须以http(s)://开头");
}
menu.setCreateBy(getUsername());
return toAjax(menuService.insertMenu(menu));
}
/**
* 修改菜单
*/
@PreAuthorize("@ss.hasPermi('system:menu:edit')")
@Log(title = "菜单管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysMenu menu)
{
if (!menuService.checkMenuNameUnique(menu))
{
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
{
return error("修改菜单'" + menu.getMenuName() + "'失败地址必须以http(s)://开头");
}
else if (menu.getMenuId().equals(menu.getParentId()))
{
return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
}
menu.setUpdateBy(getUsername());
return toAjax(menuService.updateMenu(menu));
}
/**
* 删除菜单
*/
@PreAuthorize("@ss.hasPermi('system:menu:remove')")
@Log(title = "菜单管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{menuId}")
public AjaxResult remove(@PathVariable("menuId") Long menuId)
{
if (menuService.hasChildByMenuId(menuId))
{
return warn("存在子菜单,不允许删除");
}
if (menuService.checkMenuExistRole(menuId))
{
return warn("菜单已分配,不允许删除");
}
return toAjax(menuService.deleteMenuById(menuId));
}
}

View File

@ -0,0 +1,91 @@
package com.cmvr.web.controller.system;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.system.domain.SysNotice;
import com.cmvr.system.service.ISysNoticeService;
/**
* 公告 信息操作处理
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/system/notice")
public class SysNoticeController extends BaseController
{
@Autowired
private ISysNoticeService noticeService;
/**
* 获取通知公告列表
*/
@PreAuthorize("@ss.hasPermi('system:notice:list')")
@GetMapping("/list")
public TableDataInfo list(SysNotice notice)
{
startPage();
List<SysNotice> list = noticeService.selectNoticeList(notice);
return getDataTable(list);
}
/**
* 根据通知公告编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:notice:query')")
@GetMapping(value = "/{noticeId}")
public AjaxResult getInfo(@PathVariable Long noticeId)
{
return success(noticeService.selectNoticeById(noticeId));
}
/**
* 新增通知公告
*/
@PreAuthorize("@ss.hasPermi('system:notice:add')")
@Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysNotice notice)
{
notice.setCreateBy(getUsername());
return toAjax(noticeService.insertNotice(notice));
}
/**
* 修改通知公告
*/
@PreAuthorize("@ss.hasPermi('system:notice:edit')")
@Log(title = "通知公告", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysNotice notice)
{
notice.setUpdateBy(getUsername());
return toAjax(noticeService.updateNotice(notice));
}
/**
* 删除通知公告
*/
@PreAuthorize("@ss.hasPermi('system:notice:remove')")
@Log(title = "通知公告", businessType = BusinessType.DELETE)
@DeleteMapping("/{noticeIds}")
public AjaxResult remove(@PathVariable Long[] noticeIds)
{
return toAjax(noticeService.deleteNoticeByIds(noticeIds));
}
}

View File

@ -0,0 +1,129 @@
package com.cmvr.web.controller.system;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.system.domain.SysPost;
import com.cmvr.system.service.ISysPostService;
/**
* 岗位信息操作处理
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/system/post")
public class SysPostController extends BaseController
{
@Autowired
private ISysPostService postService;
/**
* 获取岗位列表
*/
@PreAuthorize("@ss.hasPermi('system:post:list')")
@GetMapping("/list")
public TableDataInfo list(SysPost post)
{
startPage();
List<SysPost> list = postService.selectPostList(post);
return getDataTable(list);
}
@Log(title = "岗位管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:post:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysPost post)
{
List<SysPost> list = postService.selectPostList(post);
ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class);
util.exportExcel(response, list, "岗位数据");
}
/**
* 根据岗位编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:post:query')")
@GetMapping(value = "/{postId}")
public AjaxResult getInfo(@PathVariable Long postId)
{
return success(postService.selectPostById(postId));
}
/**
* 新增岗位
*/
@PreAuthorize("@ss.hasPermi('system:post:add')")
@Log(title = "岗位管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysPost post)
{
if (!postService.checkPostNameUnique(post))
{
return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
}
else if (!postService.checkPostCodeUnique(post))
{
return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
}
post.setCreateBy(getUsername());
return toAjax(postService.insertPost(post));
}
/**
* 修改岗位
*/
@PreAuthorize("@ss.hasPermi('system:post:edit')")
@Log(title = "岗位管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysPost post)
{
if (!postService.checkPostNameUnique(post))
{
return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
}
else if (!postService.checkPostCodeUnique(post))
{
return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
}
post.setUpdateBy(getUsername());
return toAjax(postService.updatePost(post));
}
/**
* 删除岗位
*/
@PreAuthorize("@ss.hasPermi('system:post:remove')")
@Log(title = "岗位管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{postIds}")
public AjaxResult remove(@PathVariable Long[] postIds)
{
return toAjax(postService.deletePostByIds(postIds));
}
/**
* 获取岗位选择框列表
*/
@GetMapping("/optionselect")
public AjaxResult optionselect()
{
List<SysPost> posts = postService.selectPostAll();
return success(posts);
}
}

View File

@ -0,0 +1,140 @@
package com.cmvr.web.controller.system;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.config.CmvrIotConfig;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.domain.entity.SysUser;
import com.cmvr.common.core.domain.model.LoginUser;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.SecurityUtils;
import com.cmvr.common.utils.StringUtils;
import com.cmvr.common.utils.file.FileUploadUtils;
import com.cmvr.common.utils.file.MimeTypeUtils;
import com.cmvr.framework.web.service.TokenService;
import com.cmvr.system.service.ISysUserService;
/**
* 个人信息 业务处理
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController
{
@Autowired
private ISysUserService userService;
@Autowired
private TokenService tokenService;
/**
* 个人信息
*/
@GetMapping
public AjaxResult profile()
{
LoginUser loginUser = getLoginUser();
SysUser user = loginUser.getUser();
AjaxResult ajax = AjaxResult.success(user);
ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
return ajax;
}
/**
* 修改用户
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult updateProfile(@RequestBody SysUser user)
{
LoginUser loginUser = getLoginUser();
SysUser currentUser = loginUser.getUser();
currentUser.setNickName(user.getNickName());
currentUser.setEmail(user.getEmail());
currentUser.setPhonenumber(user.getPhonenumber());
currentUser.setSex(user.getSex());
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser))
{
return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在");
}
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser))
{
return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在");
}
if (userService.updateUserProfile(currentUser) > 0)
{
// 更新缓存用户信息
tokenService.setLoginUser(loginUser);
return success();
}
return error("修改个人信息异常,请联系管理员");
}
/**
* 重置密码
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping("/updatePwd")
public AjaxResult updatePwd(@RequestBody Map<String, String> params)
{
String oldPassword = params.get("oldPassword");
String newPassword = params.get("newPassword");
LoginUser loginUser = getLoginUser();
String userName = loginUser.getUsername();
String password = loginUser.getPassword();
if (!SecurityUtils.matchesPassword(oldPassword, password))
{
return error("修改密码失败,旧密码错误");
}
if (SecurityUtils.matchesPassword(newPassword, password))
{
return error("新密码不能与旧密码相同");
}
newPassword = SecurityUtils.encryptPassword(newPassword);
if (userService.resetUserPwd(userName, newPassword) > 0)
{
// 更新缓存用户密码
loginUser.getUser().setPassword(newPassword);
tokenService.setLoginUser(loginUser);
return success();
}
return error("修改密码异常,请联系管理员");
}
/**
* 头像上传
*/
@Log(title = "用户头像", businessType = BusinessType.UPDATE)
@PostMapping("/avatar")
public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception
{
if (!file.isEmpty())
{
LoginUser loginUser = getLoginUser();
String avatar = FileUploadUtils.upload(CmvrIotConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
if (userService.updateUserAvatar(loginUser.getUsername(), avatar))
{
AjaxResult ajax = AjaxResult.success();
ajax.put("imgUrl", avatar);
// 更新缓存用户头像
loginUser.getUser().setAvatar(avatar);
tokenService.setLoginUser(loginUser);
return ajax;
}
}
return error("上传图片异常,请联系管理员");
}
}

View File

@ -0,0 +1,38 @@
package com.cmvr.web.controller.system;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.domain.model.RegisterBody;
import com.cmvr.common.utils.StringUtils;
import com.cmvr.framework.web.service.SysRegisterService;
import com.cmvr.system.service.ISysConfigService;
/**
* 注册验证
*
* @author cmvr-iot
*/
@RestController
public class SysRegisterController extends BaseController
{
@Autowired
private SysRegisterService registerService;
@Autowired
private ISysConfigService configService;
@PostMapping("/register")
public AjaxResult register(@RequestBody RegisterBody user)
{
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
{
return error("当前系统没有开启注册功能!");
}
String msg = registerService.register(user);
return StringUtils.isEmpty(msg) ? success() : error(msg);
}
}

View File

@ -0,0 +1,262 @@
package com.cmvr.web.controller.system;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.domain.entity.SysDept;
import com.cmvr.common.core.domain.entity.SysRole;
import com.cmvr.common.core.domain.entity.SysUser;
import com.cmvr.common.core.domain.model.LoginUser;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.StringUtils;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.framework.web.service.SysPermissionService;
import com.cmvr.framework.web.service.TokenService;
import com.cmvr.system.domain.SysUserRole;
import com.cmvr.system.service.ISysDeptService;
import com.cmvr.system.service.ISysRoleService;
import com.cmvr.system.service.ISysUserService;
/**
* 角色信息
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/system/role")
public class SysRoleController extends BaseController
{
@Autowired
private ISysRoleService roleService;
@Autowired
private TokenService tokenService;
@Autowired
private SysPermissionService permissionService;
@Autowired
private ISysUserService userService;
@Autowired
private ISysDeptService deptService;
@PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/list")
public TableDataInfo list(SysRole role)
{
startPage();
List<SysRole> list = roleService.selectRoleList(role);
return getDataTable(list);
}
@Log(title = "角色管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:role:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysRole role)
{
List<SysRole> list = roleService.selectRoleList(role);
ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
util.exportExcel(response, list, "角色数据");
}
/**
* 根据角色编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:role:query')")
@GetMapping(value = "/{roleId}")
public AjaxResult getInfo(@PathVariable Long roleId)
{
roleService.checkRoleDataScope(roleId);
return success(roleService.selectRoleById(roleId));
}
/**
* 新增角色
*/
@PreAuthorize("@ss.hasPermi('system:role:add')")
@Log(title = "角色管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysRole role)
{
if (!roleService.checkRoleNameUnique(role))
{
return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
}
else if (!roleService.checkRoleKeyUnique(role))
{
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setCreateBy(getUsername());
return toAjax(roleService.insertRole(role));
}
/**
* 修改保存角色
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
if (!roleService.checkRoleNameUnique(role))
{
return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
}
else if (!roleService.checkRoleKeyUnique(role))
{
return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setUpdateBy(getUsername());
if (roleService.updateRole(role) > 0)
{
// 更新缓存用户权限
LoginUser loginUser = getLoginUser();
if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin())
{
loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName()));
loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser()));
tokenService.setLoginUser(loginUser);
}
return success();
}
return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
}
/**
* 修改保存数据权限
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping("/dataScope")
public AjaxResult dataScope(@RequestBody SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
return toAjax(roleService.authDataScope(role));
}
/**
* 状态修改
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
role.setUpdateBy(getUsername());
return toAjax(roleService.updateRoleStatus(role));
}
/**
* 删除角色
*/
@PreAuthorize("@ss.hasPermi('system:role:remove')")
@Log(title = "角色管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{roleIds}")
public AjaxResult remove(@PathVariable Long[] roleIds)
{
return toAjax(roleService.deleteRoleByIds(roleIds));
}
/**
* 获取角色选择框列表
*/
@PreAuthorize("@ss.hasPermi('system:role:query')")
@GetMapping("/optionselect")
public AjaxResult optionselect()
{
return success(roleService.selectRoleAll());
}
/**
* 查询已分配用户角色列表
*/
@PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/authUser/allocatedList")
public TableDataInfo allocatedList(SysUser user)
{
startPage();
List<SysUser> list = userService.selectAllocatedList(user);
return getDataTable(list);
}
/**
* 查询未分配用户角色列表
*/
@PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/authUser/unallocatedList")
public TableDataInfo unallocatedList(SysUser user)
{
startPage();
List<SysUser> list = userService.selectUnallocatedList(user);
return getDataTable(list);
}
/**
* 取消授权用户
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/cancel")
public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole)
{
return toAjax(roleService.deleteAuthUser(userRole));
}
/**
* 批量取消授权用户
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/cancelAll")
public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds)
{
return toAjax(roleService.deleteAuthUsers(roleId, userIds));
}
/**
* 批量选择用户授权
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/selectAll")
public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds)
{
roleService.checkRoleDataScope(roleId);
return toAjax(roleService.insertAuthUsers(roleId, userIds));
}
/**
* 获取对应角色部门树列表
*/
@PreAuthorize("@ss.hasPermi('system:role:query')")
@GetMapping(value = "/deptTree/{roleId}")
public AjaxResult deptTree(@PathVariable("roleId") Long roleId)
{
AjaxResult ajax = AjaxResult.success();
ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
return ajax;
}
}

View File

@ -0,0 +1,256 @@
package com.cmvr.web.controller.system;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.domain.entity.SysDept;
import com.cmvr.common.core.domain.entity.SysRole;
import com.cmvr.common.core.domain.entity.SysUser;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.SecurityUtils;
import com.cmvr.common.utils.StringUtils;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.system.service.ISysDeptService;
import com.cmvr.system.service.ISysPostService;
import com.cmvr.system.service.ISysRoleService;
import com.cmvr.system.service.ISysUserService;
/**
* 用户信息
*
* @author cmvr-iot
*/
@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController
{
@Autowired
private ISysUserService userService;
@Autowired
private ISysRoleService roleService;
@Autowired
private ISysDeptService deptService;
@Autowired
private ISysPostService postService;
/**
* 获取用户列表
*/
@PreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/list")
public TableDataInfo list(SysUser user)
{
startPage();
List<SysUser> list = userService.selectUserList(user);
return getDataTable(list);
}
@Log(title = "用户管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:user:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysUser user)
{
List<SysUser> list = userService.selectUserList(user);
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
util.exportExcel(response, list, "用户数据");
}
@Log(title = "用户管理", businessType = BusinessType.IMPORT)
@PreAuthorize("@ss.hasPermi('system:user:import')")
@PostMapping("/importData")
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
List<SysUser> userList = util.importExcel(file.getInputStream());
String operName = getUsername();
String message = userService.importUser(userList, updateSupport, operName);
return success(message);
}
@PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response)
{
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
util.importTemplateExcel(response, "用户数据");
}
/**
* 根据用户编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:user:query')")
@GetMapping(value = { "/", "/{userId}" })
public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId)
{
AjaxResult ajax = AjaxResult.success();
if (StringUtils.isNotNull(userId))
{
userService.checkUserDataScope(userId);
SysUser sysUser = userService.selectUserById(userId);
ajax.put(AjaxResult.DATA_TAG, sysUser);
ajax.put("postIds", postService.selectPostListByUserId(userId));
ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
}
List<SysRole> roles = roleService.selectRoleAll();
ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
ajax.put("posts", postService.selectPostAll());
return ajax;
}
/**
* 新增用户
*/
@PreAuthorize("@ss.hasPermi('system:user:add')")
@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysUser user)
{
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkUserNameUnique(user))
{
return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
}
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
{
return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
user.setCreateBy(getUsername());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
return toAjax(userService.insertUser(user));
}
/**
* 修改用户
*/
@PreAuthorize("@ss.hasPermi('system:user:edit')")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkUserNameUnique(user))
{
return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
}
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
{
return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
user.setUpdateBy(getUsername());
return toAjax(userService.updateUser(user));
}
/**
* 删除用户
*/
@PreAuthorize("@ss.hasPermi('system:user:remove')")
@Log(title = "用户管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{userIds}")
public AjaxResult remove(@PathVariable Long[] userIds)
{
if (ArrayUtils.contains(userIds, getUserId()))
{
return error("当前用户不能删除");
}
return toAjax(userService.deleteUserByIds(userIds));
}
/**
* 重置密码
*/
@PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/resetPwd")
public AjaxResult resetPwd(@RequestBody SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
user.setUpdateBy(getUsername());
return toAjax(userService.resetPwd(user));
}
/**
* 状态修改
*/
@PreAuthorize("@ss.hasPermi('system:user:edit')")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
user.setUpdateBy(getUsername());
return toAjax(userService.updateUserStatus(user));
}
/**
* 根据用户编号获取授权角色
*/
@PreAuthorize("@ss.hasPermi('system:user:query')")
@GetMapping("/authRole/{userId}")
public AjaxResult authRole(@PathVariable("userId") Long userId)
{
AjaxResult ajax = AjaxResult.success();
SysUser user = userService.selectUserById(userId);
List<SysRole> roles = roleService.selectRolesByUserId(userId);
ajax.put("user", user);
ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
return ajax;
}
/**
* 用户授权角色
*/
@PreAuthorize("@ss.hasPermi('system:user:edit')")
@Log(title = "用户管理", businessType = BusinessType.GRANT)
@PutMapping("/authRole")
public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
{
userService.checkUserDataScope(userId);
roleService.checkRoleDataScope(roleIds);
userService.insertUserAuth(userId, roleIds);
return success();
}
/**
* 获取部门树列表
*/
@PreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/deptTree")
public AjaxResult deptTree(SysDept dept)
{
return success(deptService.selectDeptTreeList(dept));
}
}

View File

@ -0,0 +1,78 @@
package com.cmvr.web.controller.system;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.system.domain.SysVehOperConfig;
import com.cmvr.system.service.ISysVehOperConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 车机操作配置
*
* @author cmvr-iot
*/
@Api(tags = "车机操作配置")
@RestController
@RequestMapping("/system/vehOper")
@RequiredArgsConstructor
public class SysVehOperConfigController extends BaseController {
private final ISysVehOperConfigService sysVehOperConfigService;
@ApiOperation("获取车机操作配置列表")
@PreAuthorize("@ss.hasPermi('system:vehOper:list')")
@GetMapping("/list")
public TableDataInfo list(SysVehOperConfig config) {
startPage();
List<SysVehOperConfig> list = sysVehOperConfigService.selectSysVehOperConfigList(config);
return getDataTable(list);
}
@ApiOperation("根据参数编号获取详细信息")
@PreAuthorize("@ss.hasPermi('system:vehOper:query')")
@GetMapping(value = "/{configId}")
public AjaxResult getInfo(@PathVariable Long configId) {
return success(sysVehOperConfigService.selectSysVehOperConfigById(configId));
}
@ApiOperation("新增参数配置")
@PreAuthorize("@ss.hasPermi('system:vehOper:add')")
@Log(title = "参数管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysVehOperConfig config) {
return toAjax(sysVehOperConfigService.insertVehOperConfig(config));
}
@ApiOperation("修改参数配置")
@PreAuthorize("@ss.hasPermi('system:vehOper:edit')")
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysVehOperConfig config) {
return toAjax(sysVehOperConfigService.updateVehOperConfig(config));
}
@ApiOperation("删除参数配置")
@PreAuthorize("@ss.hasPermi('system:vehOper:remove')")
@Log(title = "参数管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{configIds}")
public AjaxResult remove(@PathVariable Long[] configIds) {
return success(sysVehOperConfigService.deleteVehOperConfigByIds(configIds));
}
}

View File

@ -0,0 +1,29 @@
package com.cmvr.web.controller.test;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.test.model.domain.TeAiEvaluation;
import com.cmvr.test.service.ITeAiEvaluationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "测试--AI评估")
@RestController
@RequestMapping("/test/evaluation")
@RequiredArgsConstructor
public class TeAiEvaluationController extends BaseController {
private final ITeAiEvaluationService teAiEvaluationService;
@ApiOperation("回调AI评估")
@PostMapping("/callback")
public AjaxResult list(@RequestBody TeAiEvaluation teAiEvaluation) {
return AjaxResult.ok(teAiEvaluationService.edit(teAiEvaluation));
}
}

View File

@ -0,0 +1,78 @@
package com.cmvr.web.controller.test;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.common.utils.poi.ExcelUtil;
import com.cmvr.test.model.domain.TeDetectionItem;
import com.cmvr.test.model.vo.TeDetectionItemVO;
import com.cmvr.test.service.ITeDetectionItemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@Api(tags = "测试--检测项配置")
@RestController
@RequestMapping("/test/detect")
@RequiredArgsConstructor
public class TeDetectionItemController extends BaseController {
private final ITeDetectionItemService teDetectionItemService;
@ApiOperation("查询检测项配置列表")
@PreAuthorize("@ss.hasPermi('test:detect:list')")
@GetMapping("/list")
public TableDataInfo list(TeDetectionItem teDetectionItem) {
startPage();
List<TeDetectionItemVO> list = teDetectionItemService.selectTeDetectionItemList(teDetectionItem);
return getDataTable(list);
}
@ApiOperation("导出检测项配置列表")
@PreAuthorize("@ss.hasPermi('test:detect:export')")
@Log(title = "检测项配置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, TeDetectionItem teDetectionItem) {
List<TeDetectionItemVO> list = teDetectionItemService.selectTeDetectionItemList(teDetectionItem);
ExcelUtil<TeDetectionItemVO> util = new ExcelUtil<TeDetectionItemVO>(TeDetectionItemVO.class);
util.exportExcel(response, list, "检测项配置数据");
}
@ApiOperation("获取检测项配置详细信息")
@PreAuthorize("@ss.hasPermi('test:detect:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id) {
return success(teDetectionItemService.selectTeDetectionItemById(id));
}
@ApiOperation("新增检测项配置")
@PreAuthorize("@ss.hasPermi('test:detect:add')")
@Log(title = "检测项配置", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody TeDetectionItem teDetectionItem) {
int rows = teDetectionItemService.insertTeDetectionItem(teDetectionItem);
return toAjax(rows);
}
@ApiOperation("修改检测项配置")
@PreAuthorize("@ss.hasPermi('test:detect:edit')")
@Log(title = "检测项配置", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody TeDetectionItem teDetectionItem) {
return toAjax(teDetectionItemService.updateTeDetectionItem(teDetectionItem));
}
@ApiOperation("删除检测项配置")
@PreAuthorize("@ss.hasPermi('test:detect:remove')")
@Log(title = "检测项配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(teDetectionItemService.deleteTeDetectionItemByIds(ids));
}
}

View File

@ -0,0 +1,275 @@
package com.cmvr.web.controller.test;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSONObject;
import com.cmvr.common.annotation.Anonymous;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.llm.service.LLMAiAgentPlatformService;
import com.cmvr.test.flow.context.TaskContextManager;
import com.cmvr.test.flow.control.FlowControlService;
import com.cmvr.test.flow.runtime.engine.FlowTaskRuntimeService;
import com.cmvr.test.flow.runtime.operator.edge.ti.TiTouchOperateService;
import com.cmvr.test.model.domain.TeDetectionItem;
import com.cmvr.test.model.vo.FlowActionRequestVO;
import com.cmvr.test.model.vo.TeFlowViewVO;
import com.cmvr.test.model.vo.TeTaskExecuteNormalVO;
import com.cmvr.test.model.vo.TeTaskExecuteTrailVO;
import com.cmvr.test.service.FlowActionExecutorService;
import com.cmvr.test.service.ITeDetectionItemService;
import com.cmvr.test.service.ITeNodeInstService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PreDestroy;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@Api(tags = "测试--流程服务")
@RestController
@RequestMapping("/flow")
@RequiredArgsConstructor
public class TeFlowController extends BaseController {
/**
* TTS 播放接口当前按需求固定写死在 Controller
*/
private static final String TTS_PLAY_URL = "http://localhost:8080/tts/play";
/**
* TTS 停止接口停止智能体输出时同步调用
*/
private static final String TTS_STOP_URL = "http://localhost:8080/tts/stop";
/**
* 商道智能体 AppKey当前按需求固定写死不放入配置文件
*/
private static final String AI_AGENT_API_KEY = "d9etum54shheenol3apg";
private final ITeDetectionItemService teDetectionItemService;
private final ITeNodeInstService nodeInstService;
private final FlowTaskRuntimeService flowTaskRuntimeService;
private final TaskContextManager taskContextManager;
private final FlowControlService flowControlService;
private final FlowActionExecutorService flowActionExecutorService;
private final TiTouchOperateService tiTouchOperateService;
private final LLMAiAgentPlatformService llmAiAgentPlatformService;
private final List<String> taskInstIdList = new ArrayList<>();
/**
* 智能体调用是阻塞式 query这里用单线程保存当前任务句柄便于 stop 接口中断当前请求
*/
private final ExecutorService aiAgentExecutor = Executors.newSingleThreadExecutor(runnable -> {
Thread thread = new Thread(runnable, "flow-ai-agent-query");
thread.setDaemon(true);
return thread;
});
/**
* 当前正在执行的智能体任务当前接口按同一时间只保留一个前端智能体调用处理
*/
private volatile Future<JSONObject> currentAiAgentFuture;
@ApiOperation("流程发布")
@PostMapping("/publish")
public AjaxResult publish(@RequestBody TeDetectionItem detectionItem) {
return toAjax(teDetectionItemService.publish(detectionItem.getId()));
}
@ApiOperation("演示任务执行入口")
@PostMapping("/demo")
@Anonymous
public AjaxResult demo(@Valid @RequestBody TeTaskExecuteNormalVO taskExecuteNormalVO) {
if (!taskInstIdList.isEmpty()) {
try {
taskInstIdList.forEach(flowControlService::stop);
} catch (Exception e) {
// 演示入口清理旧任务失败时继续启动新任务避免影响手动调试
}
taskInstIdList.clear();
}
String insId = flowTaskRuntimeService.executeTask(taskExecuteNormalVO);
taskInstIdList.add(insId);
return AjaxResult.success();
}
@ApiOperation("任务执行入口")
@PostMapping("/execute")
@Anonymous
public AjaxResult execute(@Valid @RequestBody TeTaskExecuteNormalVO taskExecuteNormalVO) {
return AjaxResult.success(flowTaskRuntimeService.executeTask(taskExecuteNormalVO));
}
@ApiOperation("检测项试运行入口")
@PostMapping("/executeTrial")
public AjaxResult executeTrial(@Valid @RequestBody TeTaskExecuteTrailVO taskExecuteTrailVO) {
return AjaxResult.success(flowTaskRuntimeService.executeTrialTask(taskExecuteTrailVO));
}
@ApiOperation("流程可视化")
@PostMapping("/view")
public AjaxResult view(@Valid @RequestBody TeFlowViewVO flowViewVO) {
return AjaxResult.success(nodeInstService.view(flowViewVO));
}
@ApiOperation("清理终端")
@GetMapping("/clear")
public AjaxResult clear() {
taskContextManager.clearAll();
return AjaxResult.success();
}
@ApiOperation("终止任务")
@PostMapping("/stop/{instId}")
public AjaxResult stopTask(@PathVariable String instId) {
flowControlService.stop(instId);
return AjaxResult.success();
}
@ApiOperation("暂停任务")
@PostMapping("/pause/{instId}")
public AjaxResult pauseTask(@PathVariable String instId) {
flowControlService.pause(instId);
return AjaxResult.success();
}
@ApiOperation("恢复任务")
@PostMapping("/resume/{instId}")
public AjaxResult resumeTask(@PathVariable String instId) {
flowControlService.resume(instId);
return AjaxResult.success();
}
@PostMapping("/action")
@ApiOperation(value = "单个节点执行",
notes = "巡检仪表节点action=INSPECTION_METER_RECOGNIZEpayload使用InspectionMeterRecognizeConfigVO"
+ "人工判断节点action=INSPECTION_MANUAL_REVIEW_CREATEpayload使用InspectionManualReviewConfigVO。"
+ "该接口用于试调节点,不会生成正式巡检任务结果")
public AjaxResult actionExecute(
@io.swagger.annotations.ApiParam(value = "单节点动作和参数", required = true)
@RequestBody FlowActionRequestVO flowActionRequestVO) {
return AjaxResult.ok(flowActionExecutorService.actionExecute(flowActionRequestVO));
}
/**
* 调用商道智能体平台
*
* <p>前端只需要传入 text后端固定 actionapiKey TTS 参数
* 调用会放入可取消任务中前端可以通过 /flow/llm/stop 停止当前调用并停止 TTS</p>
*/
@GetMapping("/llm/query")
@ApiOperation("调用商道智能体")
public AjaxResult queryAiAgent(String text) {
if (text == null || text.trim().isEmpty()) {
return AjaxResult.error("text不能为空");
}
stopCurrentAiAgentFuture(true);
JSONObject params = new JSONObject();
params.put("url", TTS_PLAY_URL);
params.put("voice", "x4_yezi");
params.put("speed", 45);
params.put("volume", 100);
Future<JSONObject> future = aiAgentExecutor.submit(() -> llmAiAgentPlatformService.query(
null,
text.trim(),
AI_AGENT_API_KEY,
true,
params
));
currentAiAgentFuture = future;
try {
return AjaxResult.ok(future.get());
} catch (CancellationException e) {
return AjaxResult.error("智能体调用已停止");
} catch (InterruptedException e) {
future.cancel(true);
Thread.currentThread().interrupt();
return AjaxResult.error("智能体调用被中断");
} catch (ExecutionException e) {
Throwable cause = e.getCause() == null ? e : e.getCause();
return AjaxResult.error("智能体调用失败:" + cause.getMessage());
} finally {
if (currentAiAgentFuture == future) {
currentAiAgentFuture = null;
}
}
}
/**
* 停止当前智能体调用并通知 TTS 服务停止播放
*
* <p>停止分两步先取消当前 query 任务触发底层 SSE 等待线程中断
* 再调用本地 TTS stop 接口停止已经进入播放队列的音频</p>
*/
@PostMapping("/llm/stop")
@ApiOperation("停止商道智能体和TTS")
public AjaxResult stopAiAgent() {
stopCurrentAiAgentFuture(false);
// String ttsStopResult = stopTts();
return AjaxResult.ok("ok");
}
@GetMapping("/testrun")
@ApiOperation("测试接口")
public AjaxResult testrun(@RequestParam("imageUrl") String imageUrl,
@RequestParam("iconUrl") String iconUrl) {
return AjaxResult.ok(tiTouchOperateService.test(imageUrl, iconUrl));
}
/**
* 取消当前智能体任务
*
* @param stopTts 是否同时停止 TTS 播放
*/
private void stopCurrentAiAgentFuture(boolean stopTts) {
Future<JSONObject> future = currentAiAgentFuture;
if (future != null && !future.isDone()) {
future.cancel(true);
}
currentAiAgentFuture = null;
if (stopTts) {
stopTts();
}
}
/**
* 调用本地 TTS 停止接口
*/
private String stopTts() {
try (HttpResponse response = HttpRequest.post(TTS_STOP_URL)
.timeout(3000)
.execute()) {
return response.body();
} catch (Exception e) {
return "调用TTS停止接口失败" + e.getMessage();
}
}
/**
* Spring 容器关闭时释放智能体执行线程
*/
@PreDestroy
public void destroy() {
stopCurrentAiAgentFuture(true);
aiAgentExecutor.shutdownNow();
}
}

View File

@ -0,0 +1,115 @@
package com.cmvr.web.controller.test;
import com.alibaba.fastjson2.JSONObject;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.test.flow.control.FlowControlService;
import com.cmvr.test.flow.runtime.engine.FlowTaskRuntimeService;
import com.cmvr.test.flow.runtime.operator.edge.ti.TiTouchOperateService;
import com.cmvr.test.model.vo.FlowiseActionRequestVO;
import com.cmvr.test.model.vo.FlowiseChatRequestVO;
import com.cmvr.test.model.vo.FlowiseStartRequestVO;
import com.cmvr.test.model.vo.TeTaskExecuteNormalVO;
import com.cmvr.test.service.FlowActionExecutorService;
import com.cmvr.test.service.FlowiseActionService;
import com.google.gson.JsonObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@Api(tags = "测试--flowise服务")
@RestController
@RequestMapping("/flowise")
@RequiredArgsConstructor
public class TeFlowiseController extends BaseController {
private final FlowiseActionService flowiseActionService;
private final FlowTaskRuntimeService flowTaskRuntimeService;
private final FlowControlService flowControlService;
private final FlowActionExecutorService flowActionExecutorService;
private final TiTouchOperateService tiTouchOperateService;
private final List<String> taskInstIdList = new ArrayList<>();
@ApiOperation("调用flowise")
@PostMapping("/start")
public AjaxResult start(@RequestBody FlowiseStartRequestVO request) {
JSONObject runParams = new JSONObject();
JSONObject runParams1 = new JSONObject();
runParams1
.put("test", request.getQuestion());
runParams.put("5bb26d52e1861c6936f3c3149eaf17e8", runParams1);
TeTaskExecuteNormalVO taskExecuteNormalVO = TeTaskExecuteNormalVO.builder()
.taskId("b6ab5ffff783d9b25d0dc34f13be222d")
.terminalId("4ed1246c465b97975f96c9ef8371a3bd")
.runParams(JSONObject.from(runParams)).build();
if (!taskInstIdList.isEmpty()) {
try {
taskInstIdList.forEach(flowControlService::stop);
} catch (Exception e) {
// 忽略
}
taskInstIdList.clear();
}
String insId = flowTaskRuntimeService.executeTask(taskExecuteNormalVO);
taskInstIdList.add(insId);
return AjaxResult.success();
// return AjaxResult.ok(flowiseActionService.start(request));
}
@ApiOperation("根据chatId查询执行结果")
@GetMapping("/{chatId}")
public AjaxResult query(@PathVariable String chatId) {
return AjaxResult.ok(flowiseActionService.query(chatId));
}
@ApiOperation("终止flowise")
@GetMapping("/abort")
public AjaxResult abort() {
if (!taskInstIdList.isEmpty()) {
try {
taskInstIdList.forEach(flowControlService::stop);
} catch (Exception e) {
// 忽略
}
taskInstIdList.clear();
}
logger.info("取消工作流");
return AjaxResult.success();
// return AjaxResult.ok(flowiseActionService.abort());
}
@ApiOperation("执行指令")
@PostMapping("/command")
public AjaxResult command(@RequestBody FlowiseActionRequestVO request) {
return AjaxResult.ok(flowiseActionService.command(request));
}
@ApiOperation("闲聊")
@PostMapping("/chat")
public AjaxResult chat(@RequestBody FlowiseChatRequestVO request) {
return AjaxResult.ok(flowiseActionService.chat(request));
}
@ApiOperation("动作(眨眼+动嘴+头部微动)")
@GetMapping("/action/start")
public AjaxResult actionStart() {
return AjaxResult.ok(flowiseActionService.actionStart());
}
@ApiOperation("动作停止")
@GetMapping("/action/stop")
public AjaxResult actionStop() {
return AjaxResult.ok(flowiseActionService.actionStop());
}
}

View File

@ -0,0 +1,66 @@
package com.cmvr.web.controller.test;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.test.model.domain.TeTaskConfigInfo;
import com.cmvr.test.model.vo.TeTaskConfigInfoVO;
import com.cmvr.test.service.ITeTaskConfigInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Api(tags = "测试--任务配置")
@RestController
@RequestMapping("/test/config")
@RequiredArgsConstructor
public class TeTaskConfigInfoController extends BaseController {
private final ITeTaskConfigInfoService teTaskConfigInfoService;
@ApiOperation("查询任务配置信息列表")
@PreAuthorize("@ss.hasPermi('test:config:list')")
@GetMapping("/list")
public TableDataInfo list(TeTaskConfigInfo teTaskConfigInfo) {
startPage();
List<TeTaskConfigInfoVO> list = teTaskConfigInfoService.selectTeTaskConfigInfoList(teTaskConfigInfo);
return getDataTable(list);
}
@ApiOperation("获取任务配置信息详细信息")
@PreAuthorize("@ss.hasPermi('test:config:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id) {
return success(teTaskConfigInfoService.selectTeTaskConfigInfoById(id));
}
@ApiOperation("新增任务配置信息")
@PreAuthorize("@ss.hasPermi('test:config:add')")
@Log(title = "任务配置信息", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody TeTaskConfigInfo teTaskConfigInfo) {
return toAjax(teTaskConfigInfoService.insertTeTaskConfigInfo(teTaskConfigInfo));
}
@ApiOperation("修改任务配置信息")
@PreAuthorize("@ss.hasPermi('test:config:edit')")
@Log(title = "任务配置信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody TeTaskConfigInfo teTaskConfigInfo) {
return toAjax(teTaskConfigInfoService.updateTeTaskConfigInfo(teTaskConfigInfo));
}
@ApiOperation("删除任务配置信息")
@PreAuthorize("@ss.hasPermi('test:config:remove')")
@Log(title = "任务配置信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(teTaskConfigInfoService.deleteTeTaskConfigInfoByIds(ids));
}
}

View File

@ -0,0 +1,45 @@
package com.cmvr.web.controller.test;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.test.model.domain.TeNodeInst;
import com.cmvr.test.model.vo.TeQueryTaskInstVO;
import com.cmvr.test.model.vo.TeTaskInstVO;
import com.cmvr.test.service.ITeTaskInstService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "测试--任务实例")
@RestController
@RequestMapping("/test/inst")
@RequiredArgsConstructor
public class TeTaskInstController extends BaseController {
private final ITeTaskInstService teTaskInstService;
@ApiOperation("查询任务实例列表")
@PreAuthorize("@ss.hasPermi('test:inst:list')")
@GetMapping("/list")
public TableDataInfo list(TeQueryTaskInstVO queryTaskInstVO) {
startPage();
List<TeTaskInstVO> list = teTaskInstService.selectTeTaskInstList(queryTaskInstVO);
return getDataTable(list);
}
@ApiOperation("查询节点执行日志")
@GetMapping("/log/detail")
public TableDataInfo detail(@RequestParam String instId) {
startPage();
List<TeNodeInst> list = teTaskInstService.detail(instId);
return getDataTable(list);
}
}

View File

@ -0,0 +1,48 @@
package com.cmvr.web.controller.test;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.test.model.vo.TeQueryTaskOrchestraItemVO;
import com.cmvr.test.model.vo.TeTaskOrchestraVO;
import com.cmvr.test.service.ITeTaskOrchestrationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.util.List;
@Api(tags = "测试--任务编排")
@RestController
@RequestMapping("/test/orchestration")
@RequiredArgsConstructor
class TeTaskOrchestrationController extends BaseController {
private final ITeTaskOrchestrationService teTaskOrchestrationService;
@ApiOperation("根据任务ID查询检查项编排")
@PreAuthorize("@ss.hasPermi('test:orchestration:query')")
@GetMapping
public TableDataInfo query(
@NotEmpty(message = "任务ID不能为空")
@RequestParam("taskId") String taskId
) {
startPage();
List<TeQueryTaskOrchestraItemVO> list = teTaskOrchestrationService.queryByTaskId(taskId);
return getDataTable(list);
}
@ApiOperation("新增任务编排")
@PreAuthorize("@ss.hasPermi('test:orchestration:add')")
@Log(title = "任务编排", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Valid @RequestBody TeTaskOrchestraVO taskOrchestraVO) {
return toAjax(teTaskOrchestrationService.insertTeTaskOrchestration(taskOrchestraVO));
}
}

View File

@ -0,0 +1,28 @@
package com.cmvr.web.controller.test;
import com.cmvr.common.core.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "测试--语音唤醒")
@RestController
@RequestMapping("/kws")
@RequiredArgsConstructor
public class TekKeywordsSpotController {
@ApiOperation("唤醒")
@GetMapping("/wake")
public AjaxResult wake() {
return AjaxResult.ok();
}
@ApiOperation("执行")
@GetMapping("/execute")
public AjaxResult execute() {
return AjaxResult.ok();
}
}

View File

@ -0,0 +1,100 @@
package com.cmvr.web.controller.ti;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.test.model.vo.TeTaskExecuteProjectVO;
import com.cmvr.ti.model.domain.TiProject;
import com.cmvr.ti.service.ITiProjectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "触控交互--项目管理")
@RestController
@RequestMapping("/ti/project")
@RequiredArgsConstructor
public class TiProjectController extends BaseController {
private final ITiProjectService tiProjectService;
@ApiOperation("获取项目列表")
@PreAuthorize("@ss.hasPermi('ti:project:list')")
@GetMapping("/list")
public TableDataInfo list(TiProject tiProject) {
startPage();
List<TiProject> list = tiProjectService.selectTiProjectList(tiProject);
return getDataTable(list);
}
@ApiOperation("根据id获取项目信息")
@PreAuthorize("@ss.hasPermi('ti:project:query')")
@GetMapping(value = "/{projectId}")
public AjaxResult getInfo(@PathVariable("projectId") String projectId) {
return success(tiProjectService.selectTiProjectByProjectId(projectId));
}
@ApiOperation("添加项目")
@PreAuthorize("@ss.hasPermi('ti:project:add')")
@PostMapping
public AjaxResult add(@RequestBody TiProject tiProject) {
return toAjax(tiProjectService.insertTiProject(tiProject));
}
@ApiOperation("编辑项目")
@PreAuthorize("@ss.hasPermi('ti:project:edit')")
@PutMapping
public AjaxResult edit(@RequestBody TiProject tiProject) {
return toAjax(tiProjectService.updateTiProject(tiProject));
}
@ApiOperation("删除项目")
@PreAuthorize("@ss.hasPermi('ti:project:remove')")
@DeleteMapping("/{projectIds}")
public AjaxResult remove(@PathVariable String[] projectIds) {
return toAjax(tiProjectService.deleteTiProjectByProjectIds(projectIds));
}
@ApiOperation("查询项目执行时运行参数")
@GetMapping("/queryExecuteRunParams")
public AjaxResult queryExecuteRunParams(@RequestParam("projectId") String projectId) {
return AjaxResult.ok(tiProjectService.queryExecuteRunParams(projectId));
}
@ApiOperation("执行项目")
@PostMapping("/execute")
public AjaxResult execute(@RequestBody TeTaskExecuteProjectVO taskExecuteProjectVO) {
return AjaxResult.ok(tiProjectService.executeProject(taskExecuteProjectVO));
}
@ApiOperation("查询最近一次项目执行实例id")
@GetMapping("/queryExecuteInstId/{projectId}")
public AjaxResult queryExecuteInstId(@PathVariable("projectId") String projectId) {
return AjaxResult.ok(tiProjectService.queryExecuteInstId(projectId));
}
@ApiOperation("临时执行项目评估")
@PostMapping("/evaluation")
public AjaxResult evaluation(@RequestBody List<Long> funcIds) {
tiProjectService.executeTiEvaluation(funcIds);
return AjaxResult.ok();
}
@ApiOperation("评估查询")
@GetMapping("/evaluation/{projectId}")
public AjaxResult queryEvaluation(@PathVariable("projectId") String projectId) {
return AjaxResult.ok(tiProjectService.queryEvaluation(projectId));
}
}

View File

@ -0,0 +1,70 @@
package com.cmvr.web.controller.ti;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.ti.model.domain.TiVehicleConfig;
import com.cmvr.ti.model.vo.TiVehicleConfigTreeVO;
import com.cmvr.ti.service.ITiVehicleConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "触控交互--车辆配置")
@RestController
@RequestMapping("/ti/config")
@RequiredArgsConstructor
public class TiVehicleConfigController extends BaseController {
private final ITiVehicleConfigService tiVehicleConfigService;
@ApiOperation("查询车辆配置列表")
@PreAuthorize("@ss.hasPermi('ti:config:list')")
@GetMapping("/list")
public List<TiVehicleConfigTreeVO> list() {
return tiVehicleConfigService.selectTiVehicleConfigList();
}
@ApiOperation("获取车辆配置详细信息")
@PreAuthorize("@ss.hasPermi('ti:config:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(tiVehicleConfigService.selectTiVehicleConfigById(id));
}
@ApiOperation("新增车辆配置")
@PreAuthorize("@ss.hasPermi('ti:config:add')")
@Log(title = "车辆配置", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody TiVehicleConfig tiVehicleConfig) {
return toAjax(tiVehicleConfigService.insertTiVehicleConfig(tiVehicleConfig));
}
@ApiOperation("修改车辆配置")
@PreAuthorize("@ss.hasPermi('ti:config:edit')")
@Log(title = "车辆配置", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody TiVehicleConfig tiVehicleConfig) {
return toAjax(tiVehicleConfigService.updateTiVehicleConfig(tiVehicleConfig));
}
@ApiOperation("删除车辆配置")
@PreAuthorize("@ss.hasPermi('ti:config:remove')")
@Log(title = "车辆配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(tiVehicleConfigService.deleteTiVehicleConfigByIds(ids));
}
}

View File

@ -0,0 +1,80 @@
package com.cmvr.web.controller.ti;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.ti.model.domain.TiVehicleFunction;
import com.cmvr.ti.model.vo.TiVehicleFunctionVO;
import com.cmvr.ti.service.ITiVehicleFunctionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "触控交互--车机功能")
@RestController
@RequestMapping("/ti/function")
@RequiredArgsConstructor
public class TiVehicleFunctionController extends BaseController {
private final ITiVehicleFunctionService tiVehicleFunctionService;
@ApiOperation("查询车机功能列表")
@PreAuthorize("@ss.hasPermi('ti:function:list')")
@GetMapping("/list")
public TableDataInfo list(TiVehicleFunctionVO tiVehicleFunctionVO) {
startPage();
List<TiVehicleFunction> list = tiVehicleFunctionService.selectTiVehicleFunctionList(tiVehicleFunctionVO);
return getDataTable(list);
}
@ApiOperation("获取车机功能详细信息")
@PreAuthorize("@ss.hasPermi('ti:function:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(tiVehicleFunctionService.selectTiVehicleFunctionById(id));
}
@ApiOperation("获取车机功能详细信息帶字典")
@PreAuthorize("@ss.hasPermi('ti:function:query')")
@GetMapping(value = "/detail/{id}")
public AjaxResult getDetailInfo(@PathVariable("id") Long id) {
return success(tiVehicleFunctionService.selectTiVehicleFunctionDetailById(id));
}
@ApiOperation("新增车机功能")
@PreAuthorize("@ss.hasPermi('ti:function:add')")
@Log(title = "车机功能", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody TiVehicleFunction tiVehicleConfig) {
return toAjax(tiVehicleFunctionService.insertTiVehicleFunction(tiVehicleConfig));
}
@ApiOperation("修改车机功能")
@PreAuthorize("@ss.hasPermi('ti:function:edit')")
@Log(title = "车机功能", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody TiVehicleFunction tiVehicleConfig) {
return toAjax(tiVehicleFunctionService.updateTiVehicleFunction(tiVehicleConfig));
}
@ApiOperation("删除车机功能")
@PreAuthorize("@ss.hasPermi('ti:function:remove')")
@Log(title = "车机功能", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(tiVehicleFunctionService.deleteTiVehicleFunctionByIds(ids));
}
}

View File

@ -0,0 +1,81 @@
package com.cmvr.web.controller.ti;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.test.service.ex.ExTiVehicleFunctionService;
import com.cmvr.ti.model.domain.TiVehicleUi;
import com.cmvr.ti.service.ITiVehicleFunctionService;
import com.cmvr.ti.service.ITiVehicleUiService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "触控交互--车机界面")
@RestController
@RequestMapping("/ti/ui")
@RequiredArgsConstructor
public class TiVehicleUiController extends BaseController {
private final ITiVehicleUiService tiVehicleUiService;
private final ExTiVehicleFunctionService exTiVehicleFunctionService;
@ApiOperation("查询车机功能列表")
@PreAuthorize("@ss.hasPermi('ti:ui:list')")
@GetMapping("/list")
public TableDataInfo list(TiVehicleUi tiVehicleUi) {
startPage();
List<TiVehicleUi> list = tiVehicleUiService.selectTiVehicleUiList(tiVehicleUi);
return getDataTable(list);
}
@ApiOperation("获取车机功能详细信息")
@PreAuthorize("@ss.hasPermi('ti:ui:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(tiVehicleUiService.selectTiVehicleUiById(id));
}
@ApiOperation("新增车机功能")
@PreAuthorize("@ss.hasPermi('ti:ui:add')")
@Log(title = "车机界面", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody TiVehicleUi tiVehicleUi) {
return toAjax(tiVehicleUiService.insertTiVehicleUi(tiVehicleUi));
}
@ApiOperation("修改车机功能")
@PreAuthorize("@ss.hasPermi('ti:ui:edit')")
@Log(title = "车机界面", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody TiVehicleUi tiVehicleUi) {
return toAjax(tiVehicleUiService.updateTiVehicleUi(tiVehicleUi));
}
@ApiOperation("删除车机功能")
@PreAuthorize("@ss.hasPermi('ti:ui:remove')")
@Log(title = "车机界面", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(tiVehicleUiService.deleteTiVehicleUiByIds(ids));
}
@ApiOperation("搜索路径")
@GetMapping("/findNextClickToFunction")
public AjaxResult findNextClickToFunction(Long vehicleConfigId, String currentUi, String clickFunction) {
return AjaxResult.success(exTiVehicleFunctionService.findNextClickToFunction(vehicleConfigId, currentUi, clickFunction));
}
}

View File

@ -0,0 +1,214 @@
package com.cmvr.web.controller.tts;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.tts.domain.CorpusCategory;
import com.cmvr.tts.domain.CorpusInfo;
import com.cmvr.tts.service.ICorpusInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* 车载语料数据Controller
*
* @author cmvr
*/
@RestController
@RequestMapping("/tts/corpus")
@Api(tags = "智能座舱-车载语料管理")
public class CorpusInfoController extends BaseController {
@Autowired
private ICorpusInfoService corpusInfoService;
/**
* 查询语料列表
*/
@ApiOperation("查询语料列表")
@PreAuthorize("@ss.hasPermi('tts:corpus:list')")
@GetMapping("/list")
public TableDataInfo list(CorpusInfo corpus) {
startPage();
return corpusInfoService.selectCorpusList(corpus);
}
/**
* 获取语料详细信息
*/
@ApiOperation("获取语料详细信息")
@PreAuthorize("@ss.hasPermi('tts:corpus:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id) {
return success(corpusInfoService.selectCorpusById(id));
}
/**
* 新增语料
*/
@ApiOperation("新增语料")
@PreAuthorize("@ss.hasPermi('tts:corpus:add')")
@Log(title = "车载语料", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody CorpusInfo corpus) {
return toAjax(corpusInfoService.insertCorpus(corpus));
}
/**
* 修改语料
*/
@ApiOperation("修改语料")
@PreAuthorize("@ss.hasPermi('tts:corpus:edit')")
@Log(title = "车载语料", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody CorpusInfo corpus) {
return toAjax(corpusInfoService.updateCorpus(corpus));
}
/**
* 删除语料
*/
@ApiOperation("删除语料")
@PreAuthorize("@ss.hasPermi('tts:corpus:remove')")
@Log(title = "车载语料", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(corpusInfoService.deleteCorpusByIds(ids));
}
/**
* 获取音频流
*/
@ApiOperation("获取音频流")
@PreAuthorize("@ss.hasPermi('tts:corpus:query')")
@GetMapping("/audio/{id}")
public void getAudio(@PathVariable String id, HttpServletResponse response) {
corpusInfoService.getAudioStream(id, response);
}
/**
* 上传语料音频
*/
@ApiOperation("上传语料音频")
@PreAuthorize("@ss.hasPermi('tts:corpus:edit')")
@Log(title = "车载语料", businessType = BusinessType.UPDATE)
@PostMapping("/audio/upload/{id}")
public AjaxResult uploadAudio(@PathVariable String id, @RequestParam("file") MultipartFile file) {
String path = corpusInfoService.uploadCorpusAudio(id, file);
return success(path);
}
/**
* 批量导入语料
*/
@ApiOperation("批量导入语料")
@PreAuthorize("@ss.hasPermi('tts:corpus:import')")
@Log(title = "车载语料", businessType = BusinessType.IMPORT)
@PostMapping("/import")
public AjaxResult importData(@RequestParam("file") MultipartFile file) {
Map<String, Object> result = corpusInfoService.importCorpus(file);
return success(result);
}
/**
* 查询看板统计数据
*/
@ApiOperation("查询看板统计数据")
@PreAuthorize("@ss.hasPermi('tts:corpus:query')")
@GetMapping("/dashboard/stats")
public AjaxResult getDashboardStats() {
return success(corpusInfoService.getDashboardStats());
}
/**
* 按语种统计
*/
@ApiOperation("按语种统计")
@PreAuthorize("@ss.hasPermi('tts:corpus:query')")
@GetMapping("/stats/language")
public AjaxResult getStatsByLanguage() {
return success(corpusInfoService.getStatsByLanguage());
}
/**
* 按方言统计
*/
@ApiOperation("按方言统计")
@PreAuthorize("@ss.hasPermi('tts:corpus:query')")
@GetMapping("/stats/dialect")
public AjaxResult getStatsByDialect() {
return success(corpusInfoService.getStatsByDialect());
}
/**
* 按情绪统计
*/
@ApiOperation("按情绪统计")
@PreAuthorize("@ss.hasPermi('tts:corpus:query')")
@GetMapping("/stats/emotion")
public AjaxResult getStatsByEmotion() {
return success(corpusInfoService.getStatsByEmotion());
}
/**
* 按分类统计
*/
@ApiOperation("按分类统计")
@PreAuthorize("@ss.hasPermi('tts:corpus:query')")
@GetMapping("/stats/category")
public AjaxResult getStatsByCategory() {
return success(corpusInfoService.getStatsByCategory());
}
/**
* 查询分类树
*/
@ApiOperation("查询分类树")
@PreAuthorize("@ss.hasPermi('tts:corpus:query')")
@GetMapping("/category/tree")
public AjaxResult getCategoryTree() {
return success(corpusInfoService.getCategoryTree());
}
/**
* 新增分类
*/
@ApiOperation("新增分类")
@PreAuthorize("@ss.hasPermi('tts:corpus:add')")
@Log(title = "语料分类", businessType = BusinessType.INSERT)
@PostMapping("/category")
public AjaxResult addCategory(@RequestBody CorpusCategory category) {
return toAjax(corpusInfoService.insertCategory(category));
}
/**
* 修改分类
*/
@ApiOperation("修改分类")
@PreAuthorize("@ss.hasPermi('tts:corpus:edit')")
@Log(title = "语料分类", businessType = BusinessType.UPDATE)
@PutMapping("/category")
public AjaxResult editCategory(@RequestBody CorpusCategory category) {
return toAjax(corpusInfoService.updateCategory(category));
}
/**
* 删除分类
*/
@ApiOperation("删除分类")
@PreAuthorize("@ss.hasPermi('tts:corpus:remove')")
@Log(title = "语料分类", businessType = BusinessType.DELETE)
@DeleteMapping("/category/{id}")
public AjaxResult removeCategory(@PathVariable String id) {
return toAjax(corpusInfoService.deleteCategoryById(id));
}
}

View File

@ -0,0 +1,253 @@
package com.cmvr.web.controller.tts;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.cmvr.common.annotation.Log;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.enums.BusinessType;
import com.cmvr.llm.service.LLMAiAgentPlatformService;
import com.cmvr.tts.domain.TtsSynthesizeTask;
import com.cmvr.tts.domain.vo.LlmQueryVo;
import com.cmvr.tts.service.ITtsSynthesizeTaskService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* TTS合成任务Controller
*
* @author cmvr
*/
@RestController
@RequestMapping("/tts/task")
@Api(tags = "智能座舱-TTS合成任务管理")
@RequiredArgsConstructor
public class TtsSynthesizeTaskController extends BaseController {
@Autowired
private ITtsSynthesizeTaskService ttsTaskService;
private final LLMAiAgentPlatformService llmAiAgentPlatformService;
/**
* 查询TTS合成任务列表
*/
@ApiOperation("查询TTS合成任务列表")
@PreAuthorize("@ss.hasPermi('tts:task:list')")
@GetMapping("/list")
public TableDataInfo list(TtsSynthesizeTask task) {
startPage();
return ttsTaskService.selectTtsTaskList(task);
}
/**
* 获取TTS合成任务详细信息
*/
@ApiOperation("获取TTS合成任务详细信息")
@PreAuthorize("@ss.hasPermi('tts:task:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id) {
return success(ttsTaskService.selectTtsTaskById(id));
}
/**
* 新增TTS合成任务
*/
@ApiOperation("新增TTS合成任务")
@PreAuthorize("@ss.hasPermi('tts:task:add')")
@Log(title = "TTS合成任务", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody TtsSynthesizeTask task) {
return success(ttsTaskService.insertTtsTask(task));
}
/**
* 批量新增TTS合成任务
*/
@ApiOperation("批量新增TTS合成任务")
@PreAuthorize("@ss.hasPermi('tts:task:add')")
@Log(title = "TTS合成任务", businessType = BusinessType.INSERT)
@PostMapping("/batch")
public AjaxResult batchAdd(@RequestBody List<TtsSynthesizeTask> tasks) {
return toAjax(ttsTaskService.batchInsertTtsTask(tasks));
}
/**
* 修改TTS合成任务
*/
@ApiOperation("修改TTS合成任务")
@PreAuthorize("@ss.hasPermi('tts:task:edit')")
@Log(title = "TTS合成任务", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody TtsSynthesizeTask task) {
return toAjax(ttsTaskService.updateTtsTask(task));
}
/**
* 删除TTS合成任务
*/
@ApiOperation("删除TTS合成任务")
@PreAuthorize("@ss.hasPermi('tts:task:remove')")
@Log(title = "TTS合成任务", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(ttsTaskService.deleteTtsTaskByIds(ids));
}
/**
* 重生成TTS任务
*/
@ApiOperation("重生成TTS任务")
@PreAuthorize("@ss.hasPermi('tts:task:edit')")
@Log(title = "TTS合成任务", businessType = BusinessType.UPDATE)
@PostMapping("/regenerate/{id}")
public AjaxResult regenerate(@PathVariable String id) {
return toAjax(ttsTaskService.regenerateTask(id));
}
/**
* 获取音频文件流
*/
@ApiOperation("获取音频文件流")
@PreAuthorize("@ss.hasPermi('tts:task:query')")
@GetMapping("/audio/{id}")
public void getAudio(@PathVariable String id, HttpServletResponse response) {
ttsTaskService.getAudioStream(id, response);
}
/**
* 查询看板统计数据
*/
@ApiOperation("查询看板统计数据")
@PreAuthorize("@ss.hasPermi('tts:task:query')")
@GetMapping("/dashboard/stats")
public AjaxResult getDashboardStats() {
return success(ttsTaskService.getDashboardStats());
}
/**
* 按语种统计
*/
@ApiOperation("按语种统计")
@PreAuthorize("@ss.hasPermi('tts:task:query')")
@GetMapping("/stats/language")
public AjaxResult getStatsByLanguage() {
return success(ttsTaskService.getStatsByLanguage());
}
/**
* 按音色统计
*/
@ApiOperation("按音色统计")
@PreAuthorize("@ss.hasPermi('tts:task:query')")
@GetMapping("/stats/voice")
public AjaxResult getStatsByVoice() {
return success(ttsTaskService.getStatsByVoice());
}
/**
* 按情绪统计
*/
@ApiOperation("按情绪统计")
@PreAuthorize("@ss.hasPermi('tts:task:query')")
@GetMapping("/stats/emotion")
public AjaxResult getStatsByEmotion() {
return success(ttsTaskService.getStatsByEmotion());
}
/**
* 近7日趋势
*/
@ApiOperation("近7日趋势")
@PreAuthorize("@ss.hasPermi('tts:task:query')")
@GetMapping("/stats/trend")
public AjaxResult getLast7DaysTrend() {
return success(ttsTaskService.getLast7DaysTrend());
}
/**
* 文本泛化
*/
@ApiOperation("文本泛化")
@PreAuthorize("@ss.hasPermi('tts:task:query')")
@PostMapping("/llm/query")
public AjaxResult llmQuery(@RequestBody LlmQueryVo request) {
// 闲聊key d9672ql4shh4136opsfg
// 泛化key d966pq54shh4nveh8d20
JSONObject result = llmAiAgentPlatformService.query(
null,
request.getLanguage() + "," + request.getCount() + "," + request.getText(),
"d96ammd4shh4nvehb6mg",
false,
null
);
// 解析LLM返回的结果提取JSON数组
String resultStr = result.getString("result");
if (resultStr != null && !resultStr.isEmpty()) {
// 尝试多种格式解析
JSONArray jsonArray = parseJsonArray(resultStr);
return success(jsonArray);
}
return success(new JSONArray());
}
/**
* 解析JSON数组兼容多种格式
*/
private JSONArray parseJsonArray(String text) {
if (text == null || text.isEmpty()) {
return new JSONArray();
}
// 1. 直接尝试解析为JSON数组
try {
return JSONArray.parseArray(text);
} catch (Exception e) {
// 继续尝试其他格式
}
// 2. 移除markdown代码块标记
String cleaned = text.replace("```json", "").replace("```", "").trim();
try {
return JSONArray.parseArray(cleaned);
} catch (Exception e) {
// 继续尝试其他格式
}
// 3. 尝试从文本中提取JSON数组匹配 [...] 格式
int startIdx = text.indexOf("[");
int endIdx = text.lastIndexOf("]");
if (startIdx != -1 && endIdx != -1 && endIdx > startIdx) {
String jsonStr = text.substring(startIdx, endIdx + 1);
try {
return JSONArray.parseArray(jsonStr);
} catch (Exception e) {
// 继续尝试其他格式
}
}
// 4. 如果都失败返回包含原始文本的数组
return new JSONArray().fluentAdd(text);
}
/**
* 保存任务到语料库
*/
@ApiOperation("保存任务到语料库")
@PreAuthorize("@ss.hasPermi('tts:task:edit')")
@Log(title = "TTS合成任务", businessType = BusinessType.INSERT)
@PostMapping("/Nsave-to-corpus/{taskId}/{categoryId}")
public AjaxResult saveToCorpus(@PathVariable String taskId, @PathVariable String categoryId) {
return toAjax(ttsTaskService.saveToCorpus(taskId, categoryId));
}
}

View File

@ -0,0 +1,110 @@
package com.cmvr.web.controller.vi;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.vi.model.domain.ViCorpus;
import com.cmvr.vi.model.vo.ViContinuousCorpusVO;
import com.cmvr.vi.model.vo.ViCorpusVO;
import com.cmvr.vi.service.IViCorpusService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "语音交互--语料库")
@RestController
@RequestMapping("/vi/corpus")
@RequiredArgsConstructor
public class ViCorpusController extends BaseController {
private final IViCorpusService viCorpusService;
@ApiOperation("根据id获取语料详细信息")
@PreAuthorize("@ss.hasPermi('vi:corpus:query')")
@GetMapping(value = "/{corpusId}")
public AjaxResult getInfo(@PathVariable("corpusId") Long corpusId) {
return success(viCorpusService.selectViCorpusByCorpusId(corpusId));
}
// ----------------------- 单次对话语料/唤醒语料 --------------------------
@ApiOperation(value = "查询单次对话语料/唤醒语料列表")
@PreAuthorize("@ss.hasPermi('vi:corpus:list')")
@GetMapping("/single/list")
public TableDataInfo list(ViCorpusVO viCorpusVO) {
startPage();
List<ViCorpus> list = viCorpusService.selectViCorpusList(viCorpusVO);
return getDataTable(list);
}
@ApiOperation("新增单次对话语料/唤醒语料")
@PreAuthorize("@ss.hasPermi('vi:corpus:add')")
@PostMapping
public AjaxResult add(@RequestBody ViCorpus viCorpus) {
return toAjax(viCorpusService.insertViCorpus(viCorpus));
}
@ApiOperation("批量新增单次对话语料/唤醒语料")
@PreAuthorize("@ss.hasPermi('vi:corpus:add')")
@PostMapping("/insertBatch")
public AjaxResult insertBatch(@RequestBody List<ViCorpus> data) {
return toAjax(viCorpusService.insertBatch(data));
}
@ApiOperation("删除单次对话语料/唤醒语料")
@PreAuthorize("@ss.hasPermi('vi:corpus:remove')")
@DeleteMapping("/{corpusIds}")
public AjaxResult remove(@PathVariable Long[] corpusIds) {
return toAjax(viCorpusService.deleteViCorpusByCorpusIds(corpusIds));
}
@ApiOperation("修改单次对话语料/唤醒语料")
@PreAuthorize("@ss.hasPermi('vi:corpus:edit')")
@PutMapping
public AjaxResult edit(@RequestBody ViCorpus viCorpus) {
return toAjax(viCorpusService.updateViCorpus(viCorpus));
}
// ----------------------- 连续对话 --------------------------
@ApiOperation("查询连续对话列表")
@PreAuthorize("@ss.hasPermi('vi:corpus:list')")
@GetMapping("/continuous/list")
public TableDataInfo continuousList(ViCorpusVO viCorpusVO) {
startPage();
List<ViContinuousCorpusVO> list = viCorpusService.selectContinuousList(viCorpusVO);
return getDataTable(list);
}
@ApiOperation("新增连续对话")
@PreAuthorize("@ss.hasPermi('vi:corpus:add')")
@PostMapping("/continuous/insert")
public AjaxResult add(@RequestBody ViContinuousCorpusVO viContinuousCorpusVO) {
return toAjax(viCorpusService.insertContinuousViCorpus(viContinuousCorpusVO));
}
@ApiOperation("修改连续对话")
@PreAuthorize("@ss.hasPermi('vi:corpus:edit')")
@PostMapping("/continuous/update")
public AjaxResult update(@RequestBody ViContinuousCorpusVO viContinuousCorpusVO) {
return toAjax(viCorpusService.updateContinuousViCorpus(viContinuousCorpusVO));
}
@ApiOperation("删除连续对话")
@PreAuthorize("@ss.hasPermi('vi:corpus:remove')")
@DeleteMapping("/continuous")
public AjaxResult continuousRemove(@RequestBody String[] parentIds) {
return toAjax(viCorpusService.deleteViCorpusByParentIds(parentIds));
}
}

View File

@ -0,0 +1,93 @@
package com.cmvr.web.controller.vi;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.test.model.vo.TeTaskExecuteProjectVO;
import com.cmvr.vi.model.domain.ViProject;
import com.cmvr.vi.service.IViProjectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "语音交互--项目管理")
@RestController
@RequestMapping("/vi/project")
@RequiredArgsConstructor
public class ViProjectController extends BaseController {
private final IViProjectService viProjectService;
@ApiOperation("获取项目列表")
@PreAuthorize("@ss.hasPermi('vi:project:list')")
@GetMapping("/list")
public TableDataInfo list(ViProject viProject) {
startPage();
List<ViProject> list = viProjectService.selectViProjectList(viProject);
return getDataTable(list);
}
@ApiOperation("根据id获取项目信息")
@PreAuthorize("@ss.hasPermi('vi:project:query')")
@GetMapping(value = "/{projectId}")
public AjaxResult getInfo(@PathVariable("projectId") String projectId) {
return success(viProjectService.selectViProjectByProjectId(projectId));
}
@ApiOperation("添加项目")
@PreAuthorize("@ss.hasPermi('vi:project:add')")
@PostMapping
public AjaxResult add(@RequestBody ViProject viProject) {
return toAjax(viProjectService.insertViProject(viProject));
}
@ApiOperation("编辑项目")
@PreAuthorize("@ss.hasPermi('vi:project:edit')")
@PutMapping
public AjaxResult edit(@RequestBody ViProject viProject) {
return toAjax(viProjectService.updateViProject(viProject));
}
@ApiOperation("删除项目")
@PreAuthorize("@ss.hasPermi('vi:project:remove')")
@DeleteMapping("/{projectIds}")
public AjaxResult remove(@PathVariable String[] projectIds) {
return toAjax(viProjectService.deleteViProjectByProjectIds(projectIds));
}
@ApiOperation("查询项目执行时运行参数")
@GetMapping("/queryExecuteRunParams")
public AjaxResult queryExecuteRunParams(@RequestParam("projectId") String projectId) {
return AjaxResult.ok(viProjectService.queryExecuteRunParams(projectId));
}
@ApiOperation("执行项目")
@PostMapping("/execute")
public AjaxResult execute(@RequestBody TeTaskExecuteProjectVO taskExecuteProjectVO) {
return AjaxResult.ok(viProjectService.executeProject(taskExecuteProjectVO));
}
@ApiOperation("查询最近一次项目执行实例id")
@GetMapping("/queryExecuteInstId/{projectId}")
public AjaxResult queryExecuteInstId(@PathVariable("projectId") String projectId) {
return AjaxResult.ok(viProjectService.queryExecuteInstId(projectId));
}
@ApiOperation("评估查询")
@GetMapping("/evaluation/{projectId}")
public AjaxResult queryEvaluation(@PathVariable("projectId") String projectId) {
return AjaxResult.ok(viProjectService.queryEvaluation(projectId));
}
}

View File

@ -0,0 +1,66 @@
package com.cmvr.web.controller.vi;
import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.vi.model.domain.ViScheme;
import com.cmvr.vi.service.IViSchemeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "语音交互--方案")
@RestController
@RequestMapping("/vi/scheme")
@RequiredArgsConstructor
public class ViSchemeController extends BaseController {
private final IViSchemeService viSchemeService;
@ApiOperation("查询方案列表")
@PreAuthorize("@ss.hasPermi('vi:scheme:list')")
@GetMapping("/list")
public TableDataInfo list(ViScheme viScheme) {
startPage();
List<ViScheme> list = viSchemeService.selectViSchemeList(viScheme);
return getDataTable(list);
}
@ApiOperation("根据ID查询方案详细信息")
@PreAuthorize("@ss.hasPermi('vi:scheme:query')")
@GetMapping(value = "/{schemeId}")
public AjaxResult getInfo(@PathVariable("schemeId") String schemeId) {
return success(viSchemeService.selectViSchemeBySchemeId(schemeId));
}
@ApiOperation("新增方案")
@PreAuthorize("@ss.hasPermi('vi:scheme:add')")
@PostMapping
public AjaxResult add(@RequestBody ViScheme viScheme) {
return toAjax(viSchemeService.insertViScheme(viScheme));
}
@ApiOperation("修改方案")
@PreAuthorize("@ss.hasPermi('vi:scheme:edit')")
@PutMapping
public AjaxResult edit(@RequestBody ViScheme viScheme) {
return toAjax(viSchemeService.updateViScheme(viScheme));
}
@ApiOperation("删除方案")
@PreAuthorize("@ss.hasPermi('vi:scheme:remove')")
@DeleteMapping("/{schemeIds}")
public AjaxResult remove(@PathVariable String[] schemeIds) {
return toAjax(viSchemeService.deleteViSchemeBySchemeIds(schemeIds));
}
}

View File

@ -0,0 +1,140 @@
package com.cmvr.web.core.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.cmvr.common.config.CmvrIotConfig;
import com.cmvr.test.model.vo.inspection.InspectionAlarmRuleVO;
import com.cmvr.test.model.vo.inspection.InspectionManualReviewConfigVO;
import com.cmvr.test.model.vo.inspection.InspectionMediaVO;
import com.cmvr.test.model.vo.inspection.InspectionMeterRecognizeConfigVO;
import com.fasterxml.classmate.TypeResolver;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
/**
* Swagger2的接口配置
*
* @author cmvr-iot
*/
@Configuration
public class SwaggerConfig
{
/** 系统基础配置 */
@Autowired
private CmvrIotConfig cmvrIotConfig;
/** 用于将动态工作流payload对应的参数模型显式加入Swagger文档。 */
@Autowired
private TypeResolver typeResolver;
/** 是否开启swagger */
@Value("${swagger.enabled}")
private boolean enabled;
/** 设置请求的统一前缀 */
@Value("${swagger.pathMapping}")
private String pathMapping;
/**
* 创建API
*/
@Bean
public Docket createRestApi()
{
return new Docket(DocumentationType.OAS_30)
// 是否启用Swagger
.enable(enabled)
// 用来创建该API的基本信息展示在文档的页面中自定义展示的信息
.apiInfo(apiInfo())
// 设置哪些接口暴露给Swagger展示
.select()
// 扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// 扫描指定包中的swagger注解
// .apis(RequestHandlerSelectors.basePackage("com.cmvr.project.tool.swagger"))
// 扫描所有 .apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
// 工作流单节点接口使用JSONObject作为payload需显式注册巡检节点参数模型
.additionalModels(
typeResolver.resolve(InspectionMeterRecognizeConfigVO.class),
typeResolver.resolve(InspectionAlarmRuleVO.class),
typeResolver.resolve(InspectionManualReviewConfigVO.class),
typeResolver.resolve(InspectionMediaVO.class))
/* 设置安全模式swagger可以设置访问token */
.securitySchemes(securitySchemes())
.securityContexts(securityContexts())
.pathMapping(pathMapping);
}
/**
* 安全模式这里指定token通过Authorization头请求头传递
*/
private List<SecurityScheme> securitySchemes()
{
List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
return apiKeyList;
}
/**
* 安全上下文
*/
private List<SecurityContext> securityContexts()
{
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(
SecurityContext.builder()
.securityReferences(defaultAuth())
.operationSelector(o -> o.requestMappingPattern().matches("/.*"))
.build());
return securityContexts;
}
/**
* 默认的安全上引用
*/
private List<SecurityReference> defaultAuth()
{
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
/**
* 添加摘要信息
*/
private ApiInfo apiInfo()
{
// 用ApiInfoBuilder进行定制
return new ApiInfoBuilder()
// 设置标题
.title("标题招商车研物联网平台管理系统_接口文档")
// 描述
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
// 作者信息
.contact(new Contact(cmvrIotConfig.getName(), null, null))
// 版本
.version("版本号:" + cmvrIotConfig.getVersion())
.build();
}
}

View File

@ -0,0 +1 @@
restart.include.json=/com.alibaba.fastjson2.*.jar

View File

@ -0,0 +1,139 @@
server:
# 服务器的HTTP端口默认为8080
port: 13080
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://192.168.28.10:3306/cmvr-iot-dev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: cmvr2468
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url:
username:
password:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置连接超时时间
connectTimeout: 30000
# 配置网络超时时间
socketTimeout: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: cmvr-iot
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
# redis 配置
redis:
# 地址
host: 192.168.28.10
# 端口默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password: cmvr2468
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池:中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# Minio配置
minio:
url: http://192.168.28.10:9000
accessKey: AKICMVR
secretKey: wJalrXUtnFEMI
bucketName: cmvr-iot
# gRPC 客户端设置
grpc:
client:
grpc-server: # 自定义服务名
address: 'static://10.148.108.100:50051' # 调用 gRPC 的地址
# address: 'static://10.148.108.100:50051' # 调用 gRPC 的地址
enableKeepAlive: true
keepAliveWithoutCalls: true
negotiationType: plaintext # 明文传输
api:
app-id: d0epfibvo3em6c4iul40
app-key: d0eqt1kqek3vg7g4ofi0
work-flow-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/run_app_workflow
query-result-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/query_run_app_process
bge-vl: http://192.168.1.8:5000/search_similar
generate_advanced_audio: http://192.168.0.102:9003/generate_advanced_audio
# 智能体应用id和秘钥
# ActionEnum 的枚举作为 key
agents:
INTENT_RECOGNITION: # 意图识别
app-id: d5dn5ibp9adhq1b34lig
app-key: d6j5bcellh49on5tasvg
TI_TOUCH_COORDINATES: # 获取触控二维坐标
app-id: d1ebtabnjkflk4gmhikg
app-key: d5thge2cktmipk78h82g
evaluation: http://192.168.0.8:8000/analyze
current-page: http://192.168.0.222:5000/search_similar
flowise:
tts: 192.168.0.222:8080/tts/
start: http://192.168.0.108:3000/api/v1/prediction/f99329e9-b33d-437d-90ed-69eaa8a05418
abort: http://192.168.0.108:3000/api/v1/chatmessage/abort/f99329e9-b33d-437d-90ed-69eaa8a05418/
query: http://192.168.0.108:3000/api/v1/executions/
api-key: pg61JW6W_GXyqmqSoURJ4mlSRrCMRzGLBJli_w3BFkg
# TTS外部接口配置
tts:
external-api:
url: http://192.168.0.102:9003/generate_advanced_audio

View File

@ -0,0 +1,134 @@
server:
# 服务器的HTTP端口默认为8080
port: 13080
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://192.168.0.100:3306/cmvr-iot-dev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: cmvr-iot
password: cmvr-iot123456
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url:
username:
password:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置连接超时时间
connectTimeout: 30000
# 配置网络超时时间
socketTimeout: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: cmvr-iot
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
# redis 配置
redis:
# 地址
host: 192.168.0.100
# 端口默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password: cmvr2468
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池:中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# Minio配置
minio:
url: http://192.168.0.100:9000
accessKey: AKICMVR
secretKey: wJalrXUtnFEMI
bucketName: cmvr-iot
# gRPC 客户端设置
grpc:
client:
grpc-server: # 自定义服务名
address: 'static://10.148.108.100:50051' # 调用 gRPC 的地址
# address: 'static://10.148.108.100:50051' # 调用 gRPC 的地址
enableKeepAlive: true
keepAliveWithoutCalls: true
negotiationType: plaintext # 明文传输
api:
app-id: d0epfibvo3em6c4iul40
app-key: d0eqt1kqek3vg7g4ofi0
work-flow-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/run_app_workflow
query-result-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/query_run_app_process
bge-vl: http://192.168.1.8:5000/search_similar
generate_advanced_audio: http://192.168.0.102:9003/generate_advanced_audio
# 智能体应用id和秘钥
# ActionEnum 的枚举作为 key
agents:
INTENT_RECOGNITION: # 意图识别
app-id: d5dn5ibp9adhq1b34lig
app-key: d6j5bcellh49on5tasvg
TI_TOUCH_COORDINATES: # 获取触控二维坐标
app-id: d1ebtabnjkflk4gmhikg
app-key: d5thge2cktmipk78h82g
evaluation: http://192.168.0.8:8000/analyze
current-page: http://192.168.0.222:5000/search_similar
flowise:
tts: 192.168.0.222:8080/tts/
start: http://192.168.0.108:3000/api/v1/prediction/f99329e9-b33d-437d-90ed-69eaa8a05418
abort: http://192.168.0.108:3000/api/v1/chatmessage/abort/f99329e9-b33d-437d-90ed-69eaa8a05418/
query: http://192.168.0.108:3000/api/v1/executions/
api-key: pg61JW6W_GXyqmqSoURJ4mlSRrCMRzGLBJli_w3BFkg

View File

@ -0,0 +1,134 @@
server:
# 服务器的HTTP端口默认为8080
port: 13080
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://192.168.28.10:3306/cmvr-iot-dev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: cmvr2468
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url:
username:
password:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置连接超时时间
connectTimeout: 30000
# 配置网络超时时间
socketTimeout: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: cmvr-iot
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
# redis 配置
redis:
# 地址
host: 192.168.28.10
# 端口默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password: cmvr2468
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池:中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# Minio配置
minio:
url: http://192.168.28.10:9000
accessKey: AKICMVR
secretKey: wJalrXUtnFEMI
bucketName: cmvr-iot
# gRPC 客户端设置
grpc:
client:
grpc-server: # 自定义服务名
address: 'static://10.148.108.100:50051' # 调用 gRPC 的地址
# address: 'static://10.148.108.100:50051' # 调用 gRPC 的地址
enableKeepAlive: true
keepAliveWithoutCalls: true
negotiationType: plaintext # 明文传输
api:
app-id: d0epfibvo3em6c4iul40
app-key: d0eqt1kqek3vg7g4ofi0
work-flow-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/run_app_workflow
query-result-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/query_run_app_process
bge-vl: http://192.168.1.8:5000/search_similar
generate_advanced_audio: http://192.168.0.102:9003/generate_advanced_audio
# 智能体应用id和秘钥
# ActionEnum 的枚举作为 key
agents:
INTENT_RECOGNITION: # 意图识别
app-id: d5dn5ibp9adhq1b34lig
app-key: d6j5bcellh49on5tasvg
TI_TOUCH_COORDINATES: # 获取触控二维坐标
app-id: d1ebtabnjkflk4gmhikg
app-key: d5thge2cktmipk78h82g
evaluation: http://192.168.0.8:8000/analyze
current-page: http://192.168.0.222:5000/search_similar
flowise:
tts: 192.168.0.222:8080/tts/
start: http://192.168.0.108:3000/api/v1/prediction/f99329e9-b33d-437d-90ed-69eaa8a05418
abort: http://192.168.0.108:3000/api/v1/chatmessage/abort/f99329e9-b33d-437d-90ed-69eaa8a05418/
query: http://192.168.0.108:3000/api/v1/executions/
api-key: pg61JW6W_GXyqmqSoURJ4mlSRrCMRzGLBJli_w3BFkg

View File

@ -0,0 +1,134 @@
server:
# 服务器的HTTP端口默认为8080
port: 13080
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://mysql57:3306/cmvr-iot-dev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: cmvr-iot
password: cmvr-iot123456
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url:
username:
password:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置连接超时时间
connectTimeout: 30000
# 配置网络超时时间
socketTimeout: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: cmvr-iot
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
# redis 配置
redis:
# 地址
host: redis
# 端口默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password: cmvr2468
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池:中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# Minio配置
minio:
url: http://minio:9000
accessKey: AKICMVR
secretKey: wJalrXUtnFEMI
bucketName: cmvr-iot
# gRPC 客户端设置
grpc:
client:
grpc-server: # 自定义服务名
address: 'static://10.148.108.100:50051' # 调用 gRPC 的地址
# address: 'static://10.148.108.100:50051' # 调用 gRPC 的地址
enableKeepAlive: true
keepAliveWithoutCalls: true
negotiationType: plaintext # 明文传输
api:
app-id: d0epfibvo3em6c4iul40
app-key: d0eqt1kqek3vg7g4ofi0
work-flow-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/run_app_workflow
query-result-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/query_run_app_process
bge-vl: http://192.168.1.8:5000/search_similar
generate_advanced_audio: http://192.168.0.102:9003/generate_advanced_audio
# 智能体应用id和秘钥
# ActionEnum 的枚举作为 key
agents:
INTENT_RECOGNITION: # 意图识别
app-id: d5dn5ibp9adhq1b34lig
app-key: d6j5bcellh49on5tasvg
TI_TOUCH_COORDINATES: # 获取触控二维坐标
app-id: d1ebtabnjkflk4gmhikg
app-key: d5thge2cktmipk78h82g
evaluation: http://192.168.0.8:8000/analyze
current-page: http://192.168.0.222:5000/search_similar
flowise:
tts: 192.168.0.222:8080/tts/
start: http://192.168.0.108:3000/api/v1/prediction/86f01c9d-aaf4-495e-9530-d02e3172c807
abort: http://192.168.0.108:3000/api/v1/chatmessage/abort/86f01c9d-aaf4-495e-9530-d02e3172c807/
query: http://192.168.0.108:3000/api/v1/executions/
api-key: pg61JW6W_GXyqmqSoURJ4mlSRrCMRzGLBJli_w3BFkg

View File

@ -0,0 +1,134 @@
server:
# 服务器的HTTP端口默认为8080
port: 13080
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://192.168.28.10:3306/cmvr-iot-dev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: cmvr2468
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url:
username:
password:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置连接超时时间
connectTimeout: 30000
# 配置网络超时时间
socketTimeout: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: cmvr-iot
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
# redis 配置
redis:
# 地址
host: 192.168.28.10
# 端口默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password: cmvr2468
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池:中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# Minio配置
minio:
url: http://192.168.28.10:9000
accessKey: AKICMVR
secretKey: wJalrXUtnFEMI
bucketName: cmvr-iot
# gRPC 客户端设置
grpc:
client:
grpc-server: # 自定义服务名
address: 'static://10.148.108.100:50051' # 调用 gRPC 的地址
# address: 'static://10.148.108.100:50051' # 调用 gRPC 的地址
enableKeepAlive: true
keepAliveWithoutCalls: true
negotiationType: plaintext # 明文传输
api:
app-id: d0epfibvo3em6c4iul40
app-key: d0eqt1kqek3vg7g4ofi0
work-flow-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/run_app_workflow
query-result-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/query_run_app_process
bge-vl: http://192.168.1.8:5000/search_similar
generate_advanced_audio: http://192.168.0.102:9003/generate_advanced_audio
# 智能体应用id和秘钥
# ActionEnum 的枚举作为 key
agents:
INTENT_RECOGNITION: # 意图识别
app-id: d5dn5ibp9adhq1b34lig
app-key: d6j5bcellh49on5tasvg
TI_TOUCH_COORDINATES: # 获取触控二维坐标
app-id: d1ebtabnjkflk4gmhikg
app-key: d5thge2cktmipk78h82g
evaluation: http://192.168.0.8:8000/analyze
current-page: http://192.168.0.222:5000/search_similar
flowise:
tts: 192.168.0.222:8080/tts/
start: http://192.168.0.108:3000/api/v1/prediction/f99329e9-b33d-437d-90ed-69eaa8a05418
abort: http://192.168.0.108:3000/api/v1/chatmessage/abort/f99329e9-b33d-437d-90ed-69eaa8a05418/
query: http://192.168.0.108:3000/api/v1/executions/
api-key: pg61JW6W_GXyqmqSoURJ4mlSRrCMRzGLBJli_w3BFkg

View File

@ -0,0 +1,119 @@
# 项目相关配置
cmvr-iot:
# 名称
name: cmvr-iot
# 版本
version: 1.0.0
# 版权年份
copyrightYear: 2025
# 文件路径 示例( Windows配置D:/cmvr-iot/uploadPathLinux配置 /home/cmvr-iot/uploadPath
profile: D:/cmvr-iot/uploadPath
# 获取ip地址开关
addressEnabled: false
# 验证码类型 math 数字计算 char 字符验证
captchaType: math
# 开发环境配置
server:
servlet:
# 应用的访问路径
context-path: /
tomcat:
# tomcat的URI编码
uri-encoding: UTF-8
# PPE报警包含Base64图片允许读取较大的JSON请求同时限制异常请求的吞入大小
max-http-form-post-size: 20MB
max-swallow-size: 20MB
# 连接数满后的排队数默认为100
accept-count: 1000
threads:
# tomcat最大线程数默认为200
max: 800
# Tomcat启动初始化的线程数默认值10
min-spare: 100
# 日志配置
logging:
level:
com.cmv: debug
org.springframework: warn
# 用户配置
user:
password:
# 密码最大错误次数
maxRetryCount: 5
# 密码锁定时间默认10分钟
lockTime: 10
# Spring配置
spring:
# 资源信息
messages:
# 国际化资源文件路径
basename: i18n/messages
profiles:
active: test
# 文件上传
servlet:
multipart:
# 单个文件大小
max-file-size: 100MB
# 设置总上传的文件大小
max-request-size: 200MB
# token配置
token:
# 令牌自定义标识
header: Authorization
# 令牌密钥
secret: abcdefghijklmnopqrstuvwxyz
# 令牌有效期默认30分钟
expireTime: 2147483647
# Mybatis-plus的配置
mybatis-plus:
# 对应的 XML 文件位置
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 实体扫描多个package用逗号或者分号分隔
typeAliasesPackage: com.cmvr.**.domain
configuration:
# 驼峰命名
mapUnderscoreToCamelCase: true
# 是否开启缓存
cacheEnabled: true
# 日志输出
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# PageHelper分页插件
pagehelper:
helperDialect: mysql
supportMethodsArguments: true
params: count=countSql
# Swagger配置
swagger:
# 是否开启swagger
enabled: true
# 请求前缀
pathMapping: /
knife4j:
# 开启屏蔽文档资源
production: false
# 是否开启Knife4jswagger 增强版)
enable: true
setting:
language: zh-CN
enableRequestCache: true
# 防止XSS攻击
xss:
# 过滤开关
enabled: true
# 排除链接(多个用逗号分隔)
excludes: /system/notice
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*,/device/*,/test/*,/api/*

View File

@ -0,0 +1,3 @@
Application Version: ${cmvr-iot.version}
Spring Boot Version: ${spring-boot.version}

View File

@ -0,0 +1,38 @@
#错误消息
not.null=* 必须填写
user.jcaptcha.error=验证码错误
user.jcaptcha.expire=验证码已失效
user.not.exists=用户不存在/密码错误
user.password.not.match=用户不存在/密码错误
user.password.retry.limit.count=密码输入错误{0}次
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
user.password.delete=对不起,您的账号已被删除
user.blocked=用户已封禁,请联系管理员
role.blocked=角色已封禁,请联系管理员
login.blocked=很遗憾访问IP已被列入系统黑名单
user.logout.success=退出成功
length.not.valid=长度必须在{min}到{max}个字符之间
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成且必须以非数字开头
user.password.not.valid=* 5-50个字符
user.email.not.valid=邮箱格式错误
user.mobile.phone.number.not.valid=手机号格式错误
user.login.success=登录成功
user.register.success=注册成功
user.notfound=请重新登录
user.forcelogout=管理员强制退出,请重新登录
user.unknown.error=未知错误,请重新登录
##文件上传消息
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB
upload.filename.exceed.length=上传的文件名最长{0}个字符
##权限
no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Some files were not shown because too many files have changed in this diff Show More