139 Commits

Author SHA1 Message Date
MichaelWin
c93a74e9a5 【改进】APP下载接口文档 2026-01-27 15:44:02 +08:00
MichaelWin
bdd48ead74 【新增】官网产品页接口 2026-01-27 15:43:35 +08:00
MichaelWin
6b793228e3 【改进】APP更新接口 2026-01-22 17:57:09 +08:00
MichaelWin
b24f647c87 【改进】API文档 2026-01-22 17:46:11 +08:00
MichaelWin
8a0032cfa4 【新增】官网获取最新APP接口 2026-01-22 17:09:12 +08:00
MichaelWin
dffa3ea84a 【改进】APP升级校验接口 2026-01-22 17:08:50 +08:00
MichaelWin
dca88d28cd 【新增】获取公共固件板载类型集合 2026-01-08 16:28:28 +08:00
MichaelWin
c07537c527 【废除】mongoDBjar包 2026-01-08 16:26:17 +08:00
MichaelWin
978eb7501b 【新增】获取公共固件版本接口 2026-01-08 15:58:34 +08:00
MichaelWin
a13fcf8440 【改进】废除mongoDB连接池 2026-01-08 15:39:10 +08:00
MichaelWin
bd8fd15b32 【新增】获取公共固件类型接口 2026-01-08 15:38:36 +08:00
MichaelWin
7807d6be80 【修复】兼容LocalDateTime以及date 2025-12-26 23:58:36 +08:00
MichaelWin
d5e423ee45 【修复】参数错误 2025-12-26 23:29:23 +08:00
MichaelWin
b93e064edc 【改进】创建与修改时间 2025-12-26 23:14:08 +08:00
MichaelWin
aefb8d0c12 【改进】接口返回数据模型参数标识 2025-12-26 23:13:28 +08:00
MichaelWin
2955df71e9 【改进】排除模型无需登录接口 2025-12-26 23:12:30 +08:00
MichaelWin
23511407ab 【改进】参数创建默认状态 2025-12-22 18:38:41 +08:00
MichaelWin
ecfe64c188 【改进】API接口文档 2025-12-22 18:36:40 +08:00
MichaelWin
58f512df4a 【改进】oss使用自定义域名 2025-12-22 18:36:18 +08:00
MichaelWin
77c1155b38 【新增】模型模块接口 2025-12-22 18:35:58 +08:00
MichaelWin
e96c54c328 【改进】后台管理系统剥离APP接口 2025-12-19 18:43:46 +08:00
MichaelWin
59307d612c 【新增】参数审核提交接口 2025-12-17 18:04:21 +08:00
MichaelWin
48800adccd 【废除】后台登录 2025-12-17 18:03:58 +08:00
2933b1961e 【改进】delete请求 2025-12-15 09:56:02 +08:00
7be8216a5a 【改进】改进用户注销接口 2025-12-15 09:50:28 +08:00
c74505b8c3 【新增】改进用户注销接口 2025-12-12 11:44:56 +08:00
8ac012f49c 【新增】用户注销接口 2025-12-11 12:55:43 +08:00
068ca75caf 【新增】用户注销接口 2025-12-11 11:42:52 +08:00
6248147389 【修复】短信验证码 2025-12-08 10:17:46 +08:00
01f18f87ba 【改进】改进版本校验规则 2025-12-06 10:50:35 +08:00
9917e46c29 【新增】APP版本更新校验功能接口 2025-12-05 17:53:44 +08:00
54cd851245 【新增】排除APP版本校验接口 2025-12-05 17:53:21 +08:00
8b13d4cd92 【改进】教程创建时间 2025-12-05 17:52:59 +08:00
46175c7295 【改进】使用顶层跳转登录 2025-12-05 11:04:30 +08:00
d72f637be3 【修复】教程分页数据接口重复问题 2025-12-05 11:04:07 +08:00
6da50d70d0 【修复】教程修改分类不生效问题 2025-12-04 18:41:26 +08:00
eec3fc663b 【新增】教程增加知识库地址 2025-12-04 17:34:53 +08:00
29bdb9ddbb 【改进】文件上传大小 2025-12-02 18:38:40 +08:00
86e0935353 【改进】文件上传大小 2025-12-02 18:34:12 +08:00
4c2cb4f0e5 【新增】反馈日志记录接口 2025-12-01 16:46:54 +08:00
3442591d2b 【优化】隐私政策 2025-11-26 14:25:31 +08:00
4928c71b19 【优化】验证码登录 2025-11-25 18:38:34 +08:00
5cd5353f97 【新增】排除验证码登录接口 2025-11-25 18:20:47 +08:00
73ab200daf 【优化】验证码登录接口 2025-11-25 18:09:51 +08:00
4298fcb402 【新增】验证码登录接口 2025-11-25 17:54:25 +08:00
37c0ac035e 【改进】统一异常捕获 2025-11-25 17:42:12 +08:00
977ca260da 【优化】忘记密码 2025-11-25 17:41:47 +08:00
4808960491 【优化】代码格式 2025-11-25 16:35:41 +08:00
74d8c66a6e 【新增】忘记密码接口 2025-11-25 16:35:11 +08:00
fca95e1203 【新增】封装账号类型校验工具 2025-11-25 16:34:19 +08:00
b7d3e07d16 【改进】账号类型校验 2025-11-25 16:33:56 +08:00
35ac70e82d 【修复】bug 2025-11-24 12:14:17 +08:00
632b37d5bd 【新增】完善后台首页面板 2025-11-21 18:39:51 +08:00
75ed266532 【新增】完善固件上传 2025-11-21 18:39:28 +08:00
884459e91a 【新增】完善固件上传 2025-11-19 09:47:45 +08:00
5acb3a34e0 【新增】OSS文件管理工具 2025-11-18 18:18:06 +08:00
9dc9bff8b1 【新增】飞行记录删除接口及数据同步 2025-11-18 18:17:44 +08:00
b44214f74a 【新增】上传飞行记录接口 2025-11-18 10:50:17 +08:00
78ff89ba0d 【修复】飞行记录接口 2025-11-18 09:33:10 +08:00
8bbb3ac38f 【新增】获取飞行记录接口 2025-11-17 18:28:20 +08:00
983f8cb429 【新增】隐私政策分类接口 2025-11-17 16:15:37 +08:00
0d9ae593c6 【改进】隐私政策分类 2025-11-17 16:15:26 +08:00
07e8151736 【优化】修改密码接口 2025-11-17 15:10:29 +08:00
ad5ca8c545 【新增】mongoDB支持 2025-11-17 15:10:09 +08:00
95e7b752e3 【改进】修改密码接口 2025-11-17 15:09:47 +08:00
3ea2777c94 【改进】隐私政策 2025-11-17 15:09:26 +08:00
1db7b3f6a1 【新增】排除咨询接口 2025-11-17 15:09:00 +08:00
03c5226a6a 【新增】咨询接口 2025-11-17 15:08:52 +08:00
7bd3d54d97 【新增】系统用户 2025-11-17 15:08:06 +08:00
61371a4a76 【改进】隐私政策 2025-11-13 16:27:46 +08:00
6606438862 【改进】密码校验 2025-11-12 09:26:59 +08:00
c9332b85db 【新增】增加跨域支持 2025-11-12 09:26:45 +08:00
74d19bb9d6 【新增】新增OSS-SDK 2025-11-12 09:26:35 +08:00
57f97a490a 【改进】固件上传 2025-11-12 09:26:16 +08:00
746e5051cf 【改进】完善教程 2025-11-12 09:25:35 +08:00
f27b57ec8b 【改进】完善教程详情页 2025-11-04 10:47:29 +08:00
5e0773a59f 【改进】更换接口 2025-11-04 10:47:15 +08:00
70ea5f4dd4 【改进】完善APP隐私协议政策 2025-11-04 10:46:57 +08:00
31ea86d90c 【新增】封装时间工具 2025-11-04 10:46:10 +08:00
73dda8b648 【新增】反馈管理 2025-11-04 10:06:20 +08:00
80a60e37af 【优化】页面组件优化,提升加载速度 2025-11-04 00:00:51 +08:00
71885c8796 【优化】固件管理 2025-11-03 23:23:51 +08:00
bfbb94481f 【改进】教程列表 2025-11-03 23:23:30 +08:00
3dcf9ca3ef 【新增】新增隐私协议 2025-11-03 23:22:25 +08:00
2b92f29a17 【优化】教程分类以及教程 2025-11-03 18:41:15 +08:00
3dbfff5f41 【新增】单行字体省略 2025-11-03 18:19:06 +08:00
f04385a306 【新增】教程指南管理 2025-11-03 18:18:37 +08:00
44f817eced 【优化】优化用户管理界面 2025-11-03 11:43:37 +08:00
0f2cc6a33c 【新增】完善固件管理 2025-11-03 11:43:11 +08:00
0d1127f25e 【新增】完善用户管理 2025-11-03 10:40:53 +08:00
bb7b4035fc 【改进】表格样式优化 2025-11-03 10:40:09 +08:00
c3b3ed3681 【新增】封装提示框 2025-11-03 10:39:46 +08:00
3fe027661b 【新增】封装提示模态框 2025-11-03 10:39:36 +08:00
74034ed26a 【改进】主页动态化 2025-10-31 17:39:24 +08:00
ad98033faa 【新增】系统用户界面 2025-10-31 17:39:05 +08:00
bd8f47d9ae 【优化】仪表盘 2025-10-31 17:38:33 +08:00
c975c205df 【改进】消息结果集 2025-10-31 17:38:17 +08:00
3ead596483 【新增】固件管理路由 2025-10-31 17:37:40 +08:00
882df50f75 【新增】仪表盘 2025-10-31 17:37:16 +08:00
13da68b90d 【新增】系统菜单控制器 2025-10-31 17:36:51 +08:00
5f8bc1af55 【新增】系统设置 2025-10-31 17:36:23 +08:00
1391239193 【新增】用户修改密码 2025-10-31 17:35:39 +08:00
fe93d9fac0 【新增】用户管理 2025-10-31 17:35:19 +08:00
6ed65f89b5 【改进】区分模块 2025-10-31 17:33:25 +08:00
9ff5b98b05 【改进】区分模块DTO 2025-10-31 17:32:54 +08:00
461c390cf7 【新增】分页参数拦截封装 2025-10-31 17:31:21 +08:00
1b9c9e9b86 【新增】分页参数拦截封装 2025-10-31 17:31:01 +08:00
be30f31990 【优化】拦截地址 2025-10-31 10:13:52 +08:00
ac4d7d8176 【改进】菜单动态化 2025-10-31 10:13:34 +08:00
54997d4e3d 【新增】实体基类 2025-10-31 10:13:13 +08:00
7bbb1be2a2 【新增】首页样式封装 2025-10-31 10:12:31 +08:00
19312e7a6f 【新增】系统菜单 2025-10-31 10:12:00 +08:00
727dd254f0 【新增】封装axios 2025-10-31 10:11:33 +08:00
2942fdabfe 【优化】优化政策协议接口 2025-10-30 16:05:23 +08:00
5ea30d6f85 【新增】排除隐私政策接口拦截 2025-10-30 12:29:30 +08:00
e6ae7d60e3 【新增】隐私政策 2025-10-30 12:29:03 +08:00
cca1847fbf 【优化】路径 2025-10-30 10:27:52 +08:00
10a317bed6 【新增】接口注释 2025-10-30 10:20:39 +08:00
a3bf673440 Merge branch 'main' of http://120.24.204.180:3000/admin/core_wing_web 2025-10-30 09:55:37 +08:00
30c4ec612a Merge remote-tracking branch 'origin/main' 2025-10-30 09:50:14 +08:00
486455af81 Merge branch 'dev_20251030' 2025-10-30 09:49:24 +08:00
e8dc76ef82 【新增】新增显示教程详情
Some checks failed
CI Build and Test / build (pull_request) Has been cancelled
2025-10-30 09:36:39 +08:00
8aa6fc0abf 【优化】拦截地址 2025-10-30 09:36:09 +08:00
7eda1a85eb 【优化】使用Thymeleaf渲染 2025-10-30 09:35:46 +08:00
6a124a5754 【删除】教程展示测试文件 2025-10-30 09:34:03 +08:00
564e617802 【改进】模块化 2025-10-30 09:32:55 +08:00
3f09aa1238 【新增】模板引擎支持包 2025-10-30 09:31:24 +08:00
b6cdbba20a Merge pull request 'dev_20251029' (#3) from dev_20251029 into main
Reviewed-on: #3
2025-10-29 10:30:41 +00:00
bc77cd244b Merge pull request #5
dev_20251029
2025-10-29 18:26:53 +08:00
5306431417 Merge pull request #4
dev_20251029
2025-10-29 18:15:44 +08:00
53287f0a1d Merge pull request #3
dev_20251029
2025-10-29 18:12:57 +08:00
efbe2a3def Merge pull request 'dev_20251029' (#2) from dev_20251029 into main
Reviewed-on: #2
2025-10-29 08:59:47 +00:00
a1cbb9fdf0 Merge pull request #2 from MakeSomeFakeNews/dev_20251029
dev_20251029
2025-10-29 16:57:06 +08:00
a84e8b9fe6 Merge pull request '【优化】优化自增id' (#1) from dev_20251028 into main
Reviewed-on: #1
2025-10-28 08:39:06 +00:00
98052c0ce7 删除 .gitea/workflows/deploy.yml 2025-10-28 07:44:22 +00:00
3780b9d2ab 删除 .gitea/workflows/ci.yml
Some checks failed
Deploy to Server / build-and-deploy (push) Has been cancelled
2025-10-28 07:44:18 +00:00
bd43d35074 删除 .gitea/workflows/README.md
Some checks failed
Deploy to Server / build-and-deploy (push) Has been cancelled
CI Build and Test / build (push) Has been cancelled
2025-10-28 07:44:03 +00:00
085cd485ad 新增后台管理
Some checks failed
CI Build and Test / build (push) Has been cancelled
Deploy to Server / build-and-deploy (push) Has been cancelled
2025-10-28 15:40:06 +08:00
9007c7de57 Merge pull request #1 from MakeSomeFakeNews/dev_20251028
Dev 20251028
2025-10-28 15:37:05 +08:00
173 changed files with 5285 additions and 1671 deletions

View File

@@ -1,211 +0,0 @@
# Gitea Actions 工作流配置说明
本项目配置了两个 Gitea Actions 工作流,用于自动化构建、测试和部署。
## 工作流列表
### 1. ci.yml - 持续集成
**触发时机:**
- 推送代码到 `main``master` 分支
- 创建 Pull Request
**执行内容:**
- 自动检出代码
- 配置 Java 8 环境
- 使用 Gradle 构建项目
- 运行单元测试
- 上传构建产物JAR 包)
- 上传测试报告
**查看结果:**
构建完成后,可以在 Gitea 仓库的 "Actions" 标签页查看运行结果和下载构建产物。
---
### 2. deploy.yml - 自动部署
**触发时机:**
- 推送代码到 `main``master` 分支
- 手动触发(在 Gitea Actions 页面点击 "Run workflow"
**执行内容:**
- 构建项目
- 通过 SCP 将 JAR 包上传到服务器
- 通过 SSH 重启应用
**配置步骤:**
#### 第一步:在 Gitea 中配置 Secrets
进入仓库 → Settings → Secrets添加以下密钥
| 密钥名称 | 说明 | 示例 |
|---------|------|------|
| `SERVER_HOST` | 服务器 IP 地址 | `120.24.204.180` |
| `SERVER_PORT` | SSH 端口 | `22` |
| `SERVER_USER` | SSH 用户名 | `root``ubuntu` |
| `SERVER_SSH_KEY` | SSH 私钥内容 | 完整的私钥文件内容 |
| `DEPLOY_PATH` | 部署目录路径 | `/opt/corewing` |
#### 第二步:生成 SSH 密钥对(如果还没有)
```bash
# 在本地生成密钥对
ssh-keygen -t rsa -b 4096 -C "gitea-deploy" -f ~/.ssh/gitea_deploy
# 查看公钥
cat ~/.ssh/gitea_deploy.pub
# 查看私钥(复制到 Gitea Secrets 中)
cat ~/.ssh/gitea_deploy
```
#### 第三步:配置服务器
```bash
# 1. SSH 登录到服务器
ssh user@your-server
# 2. 创建部署目录
sudo mkdir -p /opt/corewing
sudo chown $USER:$USER /opt/corewing
# 3. 添加公钥到 authorized_keys
echo "your-public-key-content" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# 4. 安装 Java如果未安装
sudo apt update
sudo apt install openjdk-8-jdk -y
java -version
```
#### 第四步:测试部署
推送代码到 main 分支,或在 Gitea Actions 页面手动触发 deploy 工作流。
---
## 启用 Gitea Actions
### Gitea 服务器端配置
如果你的 Gitea 实例还未启用 Actions需要管理员配置
1. **修改 Gitea 配置文件** (`app.ini`)
```ini
[actions]
ENABLED = true
DEFAULT_ACTIONS_URL = https://gitea.com
```
2. **安装 Gitea Act Runner**
```bash
# 下载 Act Runner
wget https://dl.gitea.com/act_runner/0.2.6/act_runner-0.2.6-linux-amd64
chmod +x act_runner-0.2.6-linux-amd64
mv act_runner-0.2.6-linux-amd64 /usr/local/bin/act_runner
# 注册 Runner
act_runner register --no-interactive --instance http://120.24.204.180:3000 --token YOUR_RUNNER_TOKEN
# 启动 Runner
act_runner daemon
```
3. **获取 Runner Token**
- 登录 Gitea 管理后台
- 进入 Site Administration → Actions → Runners
- 点击 "Create new Runner" 获取 Token
---
## 自定义工作流
### 修改触发条件
可以根据需要修改工作流的触发条件:
```yaml
on:
push:
branches: [ main, develop ] # 监听多个分支
tags:
- 'v*' # 监听标签
schedule:
- cron: '0 0 * * *' # 定时执行(每天午夜)
```
### 添加环境变量
在工作流中使用环境变量:
```yaml
env:
JAVA_VERSION: '8'
SPRING_PROFILES_ACTIVE: 'prod'
steps:
- name: 运行应用
run: java -jar -Dspring.profiles.active=${{ env.SPRING_PROFILES_ACTIVE }} app.jar
```
### 添加通知
可以添加构建成功/失败通知:
```yaml
- name: 发送通知
if: failure()
run: |
curl -X POST "https://your-notification-webhook" \
-d "构建失败: ${{ github.repository }}"
```
---
## 常见问题
### 1. 工作流未触发?
- 检查 Gitea Actions 是否启用
- 检查 Act Runner 是否正常运行
- 确认触发条件是否匹配
### 2. 构建失败?
- 查看 Actions 日志获取详细错误信息
- 检查 Java 版本是否正确
- 确认依赖是否能正常下载
### 3. 部署失败?
- 检查 Secrets 配置是否正确
- 测试 SSH 连接是否正常
- 检查服务器目录权限
### 4. 如何查看日志?
- Gitea 仓库 → Actions 标签页
- 点击具体的工作流运行记录
- 展开各个步骤查看详细日志
---
## 最佳实践
1. **分支策略**
- `main` 分支自动部署到生产环境
- `develop` 分支自动部署到测试环境
- Pull Request 只执行构建和测试
2. **安全性**
- 不要在代码中硬编码密码和密钥
- 使用 Secrets 管理敏感信息
- 定期轮换 SSH 密钥
3. **性能优化**
- 启用 Gradle 缓存加快构建速度
- 使用 `build -x test` 跳过测试快速构建
- 合理设置产物保留时间
4. **监控**
- 定期检查工作流运行状态
- 设置构建失败通知
- 保存构建日志便于问题排查
---
## 更多资源
- [Gitea Actions 官方文档](https://docs.gitea.io/en-us/actions/)
- [GitHub Actions 语法参考](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions)Gitea Actions 兼容 GitHub Actions 语法)
- [Act Runner 项目](https://gitea.com/gitea/act_runner)

View File

@@ -1,55 +0,0 @@
name: CI Build and Test
# 触发条件:推送到 main 分支或创建 Pull Request
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
# 1. 检出代码
- name: 检出代码
uses: actions/checkout@v3
# 2. 设置 Java 环境
- name: 设置 Java 8
uses: actions/setup-java@v3
with:
java-version: '8'
distribution: 'temurin'
cache: 'gradle'
# 3. 赋予 Gradle wrapper 执行权限
- name: 赋予 Gradle wrapper 执行权限
run: chmod +x gradlew
# 4. 构建项目(跳过测试)
- name: 使用 Gradle 构建项目
run: ./gradlew build -x test
# 5. 运行测试
- name: 运行测试
run: ./gradlew test
# 6. 上传构建产物JAR 文件)
- name: 上传 JAR 包
uses: actions/upload-artifact@v3
if: success()
with:
name: corewing-app
path: build/libs/*.jar
retention-days: 7
# 7. 上传测试报告
- name: 上传测试报告
uses: actions/upload-artifact@v3
if: always()
with:
name: test-reports
path: build/reports/tests/
retention-days: 7

View File

@@ -1,80 +0,0 @@
name: Deploy to Server
# 触发条件:手动触发或推送到 main 分支
on:
push:
branches: [ main, master ]
workflow_dispatch: # 允许手动触发
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# 1. 检出代码
- name: 检出代码
uses: actions/checkout@v3
# 2. 设置 Java 环境
- name: 设置 Java 8
uses: actions/setup-java@v3
with:
java-version: '8'
distribution: 'temurin'
cache: 'gradle'
# 3. 赋予 Gradle wrapper 执行权限
- name: 赋予 Gradle wrapper 执行权限
run: chmod +x gradlew
# 4. 构建项目
- name: 构建项目
run: ./gradlew build -x test
# 5. 打包 JAR 文件
- name: 获取 JAR 文件名
id: jar
run: echo "jar_file=$(ls build/libs/*.jar | head -n 1)" >> $GITHUB_OUTPUT
# 6. 部署到服务器(使用 SCP
# 需要在 Gitea 仓库设置中配置以下 Secrets
# - SERVER_HOST: 服务器地址
# - SERVER_PORT: SSH 端口(默认 22
# - SERVER_USER: SSH 用户名
# - SERVER_SSH_KEY: SSH 私钥
# - DEPLOY_PATH: 部署路径(如 /opt/corewing
- name: 部署到服务器
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
port: ${{ secrets.SERVER_PORT }}
source: "build/libs/*.jar"
target: ${{ secrets.DEPLOY_PATH }}
strip_components: 2
# 7. 重启应用(通过 SSH 执行命令)
- name: 重启应用
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
port: ${{ secrets.SERVER_PORT }}
script: |
cd ${{ secrets.DEPLOY_PATH }}
# 停止旧进程
pkill -f corewing || true
# 等待进程完全停止
sleep 3
# 启动新进程
nohup java -jar *.jar > app.log 2>&1 &
# 检查启动状态
sleep 5
if pgrep -f corewing > /dev/null; then
echo "应用启动成功"
else
echo "应用启动失败"
exit 1
fi

View File

@@ -34,13 +34,23 @@ dependencies {
implementation 'com.baomidou:mybatis-plus-generator' // 代码生成器
implementation("com.baomidou:mybatis-plus-jsqlparser") // SQL 解析器
implementation 'cn.dev33:sa-token-spring-boot-starter:1.44.0' // 权限认证
implementation 'cn.dev33:sa-token-redis-template:1.44.0' // Sa-Token 整合 RedisTemplate
implementation 'org.apache.commons:commons-pool2' // 提供 Redis 连接池
implementation 'com.alibaba:druid-spring-boot-starter:1.2.27' // 数据库连接池
implementation 'org.lionsoul:ip2region:2.7.0' // IP 归属地
// implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' // mongodb
compileOnly 'org.projectlombok:lombok' // Lombok
developmentOnly 'org.springframework.boot:spring-boot-devtools' // 热重载
runtimeOnly 'com.mysql:mysql-connector-j' // MySQL 驱动
annotationProcessor 'org.projectlombok:lombok' // Lombok 注解处理
testImplementation 'org.springframework.boot:spring-boot-starter-test' // 测试框架
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' // thymeleaf模版引擎
implementation 'com.aliyun.oss:aliyun-sdk-oss:3.18.3' // OSS SDK
implementation 'cn.hutool:hutool-all:5.8.40' // hutool工具包
implementation 'io.springfox:springfox-swagger2:2.10.5'
implementation 'com.github.xiaoymin:knife4j-openapi2-spring-boot-starter:4.4.0'
}
tasks.named('test') {

View File

@@ -1,6 +1,7 @@
package com.corewing.app.common;
import com.corewing.app.util.I18nUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@@ -16,21 +17,25 @@ public class Result<T> implements Serializable {
/**
* 状态码
*/
@ApiModelProperty("状态码")
private Integer code;
/**
* 返回消息
*/
@ApiModelProperty("消息内容")
private String message;
/**
* 返回数据
*/
@ApiModelProperty("数据")
private T data;
/**
* 成功标识
*/
@ApiModelProperty("是否成功")
private Boolean success;
public Result(Integer code, String message, T data, Boolean success) {
@@ -54,6 +59,13 @@ public class Result<T> implements Serializable {
return new Result<>(200, I18nUtil.getMessage("common.success"), data, true);
}
/**
* 成功返回(自定义消息)
*/
public static <T> Result<T> success(String message) {
return new Result<>(200, message, null, true);
}
/**
* 成功返回(自定义消息和数据)
*/
@@ -81,4 +93,27 @@ public class Result<T> implements Serializable {
public static <T> Result<T> error(Integer code, String message) {
return new Result<>(code, message, null, false);
}
/**
* 根据状态返回信息结果
*/
public static <T> Result<T> isBool(boolean flag) {
return flag ? Result.success() : Result.error();
}
/**
* 根据状态返回信息结果(自定义成功消息)
*/
public static <T> Result<T> isBoolAsMsg(boolean flag, String successMsg) {
return flag ? Result.success(successMsg) : Result.error();
}
/**
* 根据状态返回信息结果(自定义消息)
*/
public static <T> Result<T> isBoolAsMsg(boolean flag, String successMsg, String errorMsg) {
return flag ? Result.success(successMsg) : Result.error(errorMsg);
}
}

View File

@@ -0,0 +1,37 @@
package com.corewing.app.common.base;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Date;
@Data
public class BaseEntity {
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 创建人
*/
private String createBy;
/**
* 修改时间
*/
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
/**
* 修改人
*/
private String updateBy;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,49 @@
package com.corewing.app.common.base;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.Date;
@Getter
@Setter
public class CommonEntity implements Serializable {
/** 删除标志 */
@JsonIgnore
@TableLogic
@TableField(fill = FieldFill.INSERT)
private String deleteFlag;
/** 创建时间 */
@ApiModelProperty("创建时间")
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/** 创建人 */
@TableField(fill = FieldFill.INSERT)
private String createUser;
/** 创建人名称 */
@TableField(exist = false)
private String createUserName;
/** 更新时间 */
@ApiModelProperty("更新时间")
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
/** 更新人 */
@TableField(fill = FieldFill.UPDATE)
private String updateUser;
/** 更新人名称 */
@TableField(exist = false)
private String updateUserName;
}

View File

@@ -0,0 +1,19 @@
package com.corewing.app.common.enums;
import lombok.Getter;
/**
* 通用删除标志枚举
*
* @author xuyuxiang
* @date 2021/10/11 14:02
**/
@Getter
public enum CommonDeleteFlagEnum {
/** 未删除 */
NOT_DELETE,
/** 已删除 */
DELETED
}

View File

@@ -0,0 +1,23 @@
package com.corewing.app.common.page;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
public class PageContext {
private static final ThreadLocal<Page<?>> PAGE_HOLDER = new ThreadLocal<>();
// 设置分页对象
public static void setPage(Page<?> page) {
PAGE_HOLDER.set(page);
}
// 泛型方法:获取指定类型的分页对象(消除警告)
@SuppressWarnings("unchecked")
public static <T> Page<T> getPage(Class<T> clazz) {
return (Page<T>) PAGE_HOLDER.get();
}
// 清除线程变量
public static void clear() {
PAGE_HOLDER.remove();
}
}

View File

@@ -0,0 +1,53 @@
package com.corewing.app.common.page;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PageInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 默认分页参数
int pageNum = 1;
int pageSize = 10;
// 从请求参数中获取分页信息
String current = request.getParameter("current");
String size = request.getParameter("size");
// 解析页码
if (current != null && !current.isEmpty()) {
try {
pageNum = Integer.parseInt(current);
if (pageNum < 1) pageNum = 1; // 页码不能小于1
} catch (NumberFormatException e) {
// 非法参数使用默认值
}
}
// 解析每页条数
if (size != null && !size.isEmpty()) {
try {
pageSize = Integer.parseInt(size);
if (pageSize < 1) pageSize = 10; // 每页条数不能小于1
if (pageSize > 100) pageSize = 100; // 限制最大条数
} catch (NumberFormatException e) {
// 非法参数使用默认值
}
}
// 创建 MyBatis-Plus 的 Page 对象并存储到 ThreadLocal
Page<?> page = new Page<>(pageNum, pageSize);
PageContext.setPage(page);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 清除ThreadLocal中的数据防止内存泄漏
PageContext.clear();
}
}

View File

@@ -0,0 +1,39 @@
package com.corewing.app.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration // 标记为配置类
public class CorsConfig implements WebMvcConfigurer {
/**
* 配置跨域过滤器,优先级高于所有拦截器
*/
@Bean
public CorsFilter corsFilter() {
// 1. 配置跨域参数
CorsConfiguration config = new CorsConfiguration();
// 允许的前端域名(根据实际环境修改)
config.addAllowedOriginPattern("*");
// 允许携带 Cookie前后端都需要开启
config.setAllowCredentials(true);
// 允许的请求方法(包含预检请求 OPTIONS
config.addAllowedMethod("*");
// 允许的请求头(* 表示所有)
config.addAllowedHeader("*");
// 预检请求缓存时间1小时减少重复验证
config.setMaxAge(3600L);
// 2. 配置路径匹配规则(对所有接口生效)
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
// 3. 返回过滤器(优先级最高)
return new CorsFilter(source);
}
}

View File

@@ -0,0 +1,35 @@
package com.corewing.app.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
@Configuration
@EnableSwagger2WebMvc
public class Knife4jConfiguration {
@Bean(value = "defaultApi")
public Docket defaultApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(new ApiInfoBuilder()
.title("CoreWing APP APIs")
.description("CoreWing APP APIs")
.contact(new Contact("CoreWing", "www.corewing.com", "main@corewing.com"))
.version("1.0")
.build())
//分组名称
.groupName("1.1.0版本")
.select()
//这里指定Controller扫描包路径
.apis(RequestHandlerSelectors.basePackage("com.corewing.app.modules"))
.paths(PathSelectors.any())
.build();
}
}

View File

@@ -2,8 +2,11 @@ package com.corewing.app.config;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.stp.StpUtil;
import com.corewing.app.common.page.PageInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ResourceUtils;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
@@ -17,27 +20,51 @@ public class SaTokenConfig implements WebMvcConfigurer {
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 分页参数拦截
registry.addInterceptor(new PageInterceptor());
// 注册 Sa-Token 拦截器,校验规则为 StpUtil.checkLogin() 登录校验。
registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
// 拦截所有路由
.addPathPatterns("/**")
// 排除登录、注册、发送验证码接口
.excludePathPatterns("/user/login", "/user/register", "/user/sendCode")
// 排除登录、注册、发送验证码, 忘记密码接口
.excludePathPatterns("/user/login", "/user/register", "/user/sendCode", "/user/forgetPassword", "/user/codeLogin")
// 排除后台管理登录接口
.excludePathPatterns("/sys/user/login")
// 排除反馈接口(支持匿名提交)
.excludePathPatterns("/feedback", "/feedback/**")
// 排除教程接口(支持匿名查询)
.excludePathPatterns("/tutorial", "/tutorial/**")
// 排除隐私政策接口(支持匿名查询)
.excludePathPatterns("/privacy_policy", "/privacy_policy/**")
// 排除固件查询接口(不需要登录)
.excludePathPatterns("/firmware/**")
// 排除公共固件
.excludePathPatterns("/public_firmware/**")
// 排除系统登录页(不需要登录)
// .excludePathPatterns("/loading.html", "/admin/login.html")
// 排除静态资源
.excludePathPatterns("/", "/index.html", "/admin/login.html", "/*.css", "/*.js", "/*.ico", "/static/**")
// 排除后台管理静态资源
.excludePathPatterns("/admin/**")
.excludePathPatterns("/", "/*.css", "/*.js", "/*.ico", "/static/**", "/assets/**")
// 排除接口静态资源
.excludePathPatterns("/doc.html", "/webjars/**")
.excludePathPatterns("/v3/api-docs/swagger-config", "/v3/api-docs/**", "/swagger-resources")
// 排除 Druid 监控
.excludePathPatterns("/druid/**")
// 排除错误页面
.excludePathPatterns("/error", "/error/**");
.excludePathPatterns("/error", "/error/**")
// 排除校验更新接口
.excludePathPatterns("/app_version/**")
// 排除获取最新app接口
.excludePathPatterns("/api/app", "/api/app/getAppVersion")
.excludePathPatterns("/api/website/**")
// 排除模型接口
.excludePathPatterns("/model/page", "/model/list", "/model/detail/**", "/model/category/**")
// 排除咨询接口
.excludePathPatterns("/contactMsg", "/contactMsg/**");
}
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("doc.html").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/META-INF/resources/webjars/");
}
}

View File

@@ -1,76 +0,0 @@
package com.corewing.app.controller;
import cn.dev33.satoken.stp.StpUtil;
import com.corewing.app.common.Result;
import com.corewing.app.dto.SysLoginRequest;
import com.corewing.app.entity.SysUser;
import com.corewing.app.service.SysUserService;
import com.corewing.app.util.I18nUtil;
import com.corewing.app.util.IpUtil;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* 后台管理用户 Controller
*/
@RestController
@RequestMapping("/sys/user")
public class SysUserController {
private final SysUserService sysUserService;
public SysUserController(SysUserService sysUserService) {
this.sysUserService = sysUserService;
}
/**
* 后台管理登录
*/
@PostMapping("/login")
public Result<Map<String, Object>> login(@RequestBody SysLoginRequest request, HttpServletRequest httpRequest) {
try {
// 获取登录IP
String loginIp = IpUtil.getClientIp(httpRequest);
// 执行登录
String token = sysUserService.login(request.getUsername(), request.getPassword(), loginIp);
// 查询用户信息
SysUser user = sysUserService.getByUsername(request.getUsername());
Map<String, Object> data = new HashMap<>();
data.put("token", token);
data.put("userId", user.getId());
data.put("username", user.getUsername());
data.put("realName", user.getRealName());
return Result.success(I18nUtil.getMessage("user.login.success"), data);
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
/**
* 后台管理登出
*/
@PostMapping("/logout")
public Result<String> logout() {
StpUtil.logout();
return Result.success(I18nUtil.getMessage("user.logout.success"));
}
/**
* 获取当前登录用户信息
*/
@GetMapping("/info")
public Result<SysUser> getUserInfo() {
Long userId = StpUtil.getLoginIdAsLong();
SysUser user = sysUserService.getById(userId);
// 隐藏密码
user.setPassword(null);
return Result.success(user);
}
}

View File

@@ -0,0 +1,12 @@
package com.corewing.app.dto.AppModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ModelCategoryListRequest {
@ApiModelProperty(value = "搜索参数(分类名称)")
private String searchKey;
}

View File

@@ -0,0 +1,12 @@
package com.corewing.app.dto.AppModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ModelCategoryPageRequest {
@ApiModelProperty(value = "搜索参数(分类名称)")
private String searchKey;
}

View File

@@ -0,0 +1,37 @@
package com.corewing.app.dto.AppModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
public class ModelCreateRequest {
@ApiModelProperty(value = "模型标题", required = true)
@NotBlank(message = "模型标题不能为空")
private String title;
@ApiModelProperty(value = "模型描述", required = true)
@NotBlank(message = "模型描述不能为空")
private String description;
@ApiModelProperty(value = "模型分类id", required = true)
@NotBlank(message = "模型分类id不能为空")
private String categoryId;
@ApiModelProperty(value = "模型封面", required = true)
@NotBlank(message = "模型封面不能为空")
private String coverImage;
@ApiModelProperty(value = "备注", required = false)
private String remark;
@ApiModelProperty("模型文件")
@NotNull(message = "模型文件不能为空")
private List<MultipartFile> files;
}

View File

@@ -0,0 +1,12 @@
package com.corewing.app.dto.AppModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ModelDownloadLogListRequest {
@ApiModelProperty(value = "模型标题", required = false)
private String searchKey;
}

View File

@@ -0,0 +1,12 @@
package com.corewing.app.dto.AppModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ModelDownloadLogPageRequest {
@ApiModelProperty(value = "模型标题", required = false)
private String searchKey;
}

View File

@@ -0,0 +1,15 @@
package com.corewing.app.dto.AppModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class ModelDownloadRequest {
@ApiModelProperty(value = "模型id", required = true)
@NotBlank(message = "模型id不能为空")
private String modelId;
}

View File

@@ -0,0 +1,14 @@
package com.corewing.app.dto.AppModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class ModelFavoriteListRequest {
@ApiModelProperty(value = "模型标题", required = false)
private String searchKey;
}

View File

@@ -0,0 +1,12 @@
package com.corewing.app.dto.AppModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ModelFavoritePageRequest {
@ApiModelProperty(value = "模型标题", required = false)
private String searchKey;
}

View File

@@ -0,0 +1,15 @@
package com.corewing.app.dto.AppModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class ModelFavoriteRequest {
@ApiModelProperty(value = "模型id", required = true)
@NotBlank(message = "模型id不能为空")
private String modelId;
}

View File

@@ -0,0 +1,15 @@
package com.corewing.app.dto.AppModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class ModelIdRequest {
@ApiModelProperty(value = "模型id", required = true)
@NotBlank(message = "模型Id不能为空")
private String modelId;
}

View File

@@ -0,0 +1,15 @@
package com.corewing.app.dto.AppModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class ModelLikeRequest {
@ApiModelProperty(value = "模型id", required = true)
@NotBlank(message = "模型id不能为空")
private String modelId;
}

View File

@@ -0,0 +1,23 @@
package com.corewing.app.dto.AppModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ModelListRequest {
@ApiModelProperty(value = "用户id")
private Long userId;
@ApiModelProperty(value = "搜索参数(模型标题)")
private String searchKey;
@ApiModelProperty(value = "模型状态1正常 0下架 2审核中")
private String status;
@ApiModelProperty(value = "模型公布状态1公开 0私有")
private String isPublic;
@ApiModelProperty(value = "分类id")
private String categoryId;
}

View File

@@ -0,0 +1,24 @@
package com.corewing.app.dto.AppModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ModelPageRequest {
@ApiModelProperty(value = "用户id")
private Long userId;
@ApiModelProperty(value = "搜索参数(模型标题)")
private String searchKey;
@ApiModelProperty(value = "模型状态1正常 0下架 2审核中")
private String status;
@ApiModelProperty(value = "模型公布状态1公开 0私有")
private String isPublic;
@ApiModelProperty(value = "分类id")
private String categoryId;
}

View File

@@ -0,0 +1,19 @@
package com.corewing.app.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class CheckVersionRequest {
@NotBlank(message = "版本不能为空")
private String localVersion;
@NotBlank(message = "构建版本不能为空")
private int localBuildNumber;
@NotBlank(message = "类型不能为空")
private String type;
}

View File

@@ -0,0 +1,19 @@
package com.corewing.app.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 验证码登录请求对象
*/
@Data
public class CodeLoginRequest {
@NotBlank(message = "手机号或邮箱不能为空")
private String account;
@NotBlank(message = "验证码不能为空")
private String verificationCode;
}

View File

@@ -0,0 +1,19 @@
package com.corewing.app.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class ForgetPasswordRequest {
@NotBlank(message = "手机号或邮箱不能为空")
private String account;
@NotBlank(message = "验证码不能为空")
private String verificationCode;
@NotBlank(message = "密码不能为空")
private String password;
}

View File

@@ -0,0 +1,13 @@
package com.corewing.app.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class LogoffRequest {
@NotBlank(message = "验证码不能为空")
private String code;
}

View File

@@ -17,7 +17,7 @@ public class SendCodeRequest {
private String account;
/**
* 验证码类型register-注册, login-登录, reset-重置密码
* 验证码类型register-注册, login-登录, reset-重置密码, forget-忘记密码logoff-注销
*/
@NotBlank(message = "验证码类型不能为空")
private String type;

View File

@@ -0,0 +1,47 @@
package com.corewing.app.dto;
import lombok.Data;
@Data
public class TrajectoryData {
private Long id;
private Long session_id;
private Long timestamp;
// 基础遥测数据
private Long rc;
private Long gps;
private Long gps_status;
private double voltage;
private double cell_voltage;
private Long consumption;
private double current;
private double speed;
private double air_speed;
private double v_speed;
private double altitude;
private double distance;
private double range;
private Long throttle;
private Long wind_direction;
private double wind_speed;
private Long heading;
private double roll;
private double pitch;
private double yaw;
// 扩展数据
private double compass_heading;
private double drone_lat;
private double drone_lon;
private double home_lat;
private double home_lon;
private String map_type;
private Boolean show_trajectory;
private String flight_mode;
private Long vehicle_type;
private Long autopilot_type;
private Boolean is_armed;
private String sync_id;
}

View File

@@ -0,0 +1,7 @@
package com.corewing.app.dto;
import lombok.Data;
@Data
public class TutorialListRequest {
}

View File

@@ -0,0 +1,19 @@
package com.corewing.app.dto.publicFirmware;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class PublicBoardTypeListRequest {
@ApiModelProperty(value = "固件类型", required = true)
@NotBlank(message = "固件类型不能为空")
public String firmwareType;
@ApiModelProperty(value = "固件版本id", required = true)
@NotBlank(message = "固件版本id不能为空")
public String versionId;
}

View File

@@ -0,0 +1,23 @@
package com.corewing.app.dto.publicFirmware;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class PublicFirmwareListRequest {
@ApiModelProperty(value = "固件类型", required = true)
@NotBlank(message = "固件类型不能为空")
public String firmwareType;
@ApiModelProperty(value = "固件版本id", required = true)
@NotBlank(message = "固件版本id不能为空")
public String versionId;
@ApiModelProperty(value = "板载类型", required = true)
@NotBlank(message = "板载类型不能为空")
public String boardType;
}

View File

@@ -0,0 +1,15 @@
package com.corewing.app.dto.publicFirmware;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class PublicFirmwareVersionListRequest {
@ApiModelProperty(value = "固件类型", required = true)
@NotBlank(message = "固件类型不能为空")
public String firmwareType;
}

View File

@@ -0,0 +1,26 @@
package com.corewing.app.dto;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Data
public class uploadReplaySessionRequest {
private Long id;
private String name;
private String description;
private Long start_time;
private Long end_time;
private Long duration; // 持续时间(秒)
private Long data_count; // 数据点数量
private Date created_at;
private Date updated_at;
private String sync_id;
List<TrajectoryData> trajectoryDataList;
}

View File

@@ -0,0 +1,13 @@
package com.corewing.app.dto.website;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ProductCategoryRequest {
@ApiModelProperty(value = "产品名称")
private String searchKey;
}

View File

@@ -0,0 +1,16 @@
package com.corewing.app.dto.website;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ProductPageRequest {
@ApiModelProperty(value = "产品名称")
private String searchKey;
@ApiModelProperty(value = "产品分类")
private String categoryId;
}

View File

@@ -0,0 +1,71 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.common.base.CommonEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("app_model")
public class AppModel extends CommonEntity {
@TableId
@ApiModelProperty("模型id")
private String id;
@ApiModelProperty("用户id")
private Long userId;
@ApiModelProperty("模型标题")
private String title;
@ApiModelProperty("模型描述")
private String description;
@ApiModelProperty("分类id")
private String categoryId;
@ApiModelProperty("模型封面(base64)")
private String coverImage;
@ApiModelProperty("是否公开:(1公开0私有)")
private String isPublic;
@ApiModelProperty("状态:(1正常0下架2审核中)")
private String status;
@ApiModelProperty("下载次数")
private int downloadCount;
@ApiModelProperty("点赞次数")
private int likeCount;
@ApiModelProperty("收藏次数")
private int favoriteCount;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty("扩展参数")
private String extJson;
@ApiModelProperty("暂未使用【点击详情接口获取文件模型】")
@TableField(exist = false)
private List<AppModelFile> modelFile;
/**
* 分类名称
*/
@ApiModelProperty("分类名称")
@TableField(exist = false)
private String categoryTitle;
}

View File

@@ -0,0 +1,35 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.common.base.CommonEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("app_model_category")
public class AppModelCategory extends CommonEntity {
@TableId
@ApiModelProperty("分类id")
private String id;
@ApiModelProperty("分类名称")
private String name;
@ApiModelProperty("父级id")
private String parentId;
@ApiModelProperty("排序码")
private int sortCode;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty("扩展参数")
private String extJson;
}

View File

@@ -0,0 +1,36 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.common.base.CommonEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("app_model_download_log")
public class AppModelDownloadLog extends CommonEntity {
@TableId
@ApiModelProperty("id")
private String id;
@ApiModelProperty("用户id")
private Long userId;
@ApiModelProperty("模型id")
private String modelId;
@ApiModelProperty("下载ip")
private String ipAddress;
@ApiModelProperty("下载备注")
private String remark;
@ApiModelProperty("扩展参数")
private String extJson;
}

View File

@@ -0,0 +1,25 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.common.base.CommonEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("app_model_favorite")
public class AppModelFavorite extends CommonEntity {
@TableId
private Long id;
private Long userId;
private String modelId;
private String remark;
private String extJson;
}

View File

@@ -0,0 +1,38 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.common.base.CommonEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("app_model_file")
public class AppModelFile extends CommonEntity {
@TableId
@ApiModelProperty("id")
private String id;
@ApiModelProperty("模型id")
private String modelId;
@ApiModelProperty("文件名称")
private String fileName;
@ApiModelProperty("文件类型")
private String fileType;
@ApiModelProperty("文件大小")
private Long fileSize;
@ApiModelProperty("文件地址")
private String fileUrl;
@ApiModelProperty("文件排序")
private int sortCode;
}

View File

@@ -0,0 +1,86 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.common.base.CommonEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/**
* 固件详情表
*/
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("app_public_firmware_plane")
public class AppPublicFirmwarePlane extends CommonEntity {
/**
* 主键
*/
@TableId
private String id;
/**
* 版本号Id
*/
private String versionId;
/**
* 板载类型
*/
private String boardType;
/**
* 固件类型
*/
private String type;
/**
* 固件下载地址
*/
private String downloadUrl;
/**
* 固件名称
*/
private String firmwareName;
/**
* 固件大小
*/
private Long fileSize;
/**
* 固件发布时间
*/
private Date releaseTime;
/**
* 固件同步时间
*/
private Date crawlTime;
/**
* 是否有效
*/
private int isValid;
/**
* 排序
*/
private int sortCode;
/**
* 备注
*/
private String remark;
/**
* 扩展字段
*/
private String extJson;
}

View File

@@ -0,0 +1,65 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.common.base.CommonEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/**
* 公共固件版本表
*/
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("app_public_firmware_version")
public class AppPublicFirmwareVersion extends CommonEntity {
/**
* 主键
*/
@TableId
public String id;
/**
* 固件版本类型
*/
private String type;
/**
* 版本类型
*/
private String versionType;
/**
* 版本号
*/
private String versionNumber;
/**
* 数字版本号
*/
private int versionCode;
/**
* 发布时间
*/
private Date releaseDate;
/**
* 排序
*/
private int sortCode;
/**
* 备注
*/
private String remark;
/**
* 扩展字段
*/
private String extJson;
}

View File

@@ -0,0 +1,38 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;
/**
* app版本控制
*/
@Data
@TableName("app_version")
public class AppVersion {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String version;
private int versionNumber;
private int buildNumber;
private String updateContent;
private String downloadUrl;
private String type;
private Integer status;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,50 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.common.base.CommonEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 字典实体
*
* @author xuyuxiang
* @date 2022/2/23 18:27
**/
@Getter
@Setter
@TableName("DEV_DICT")
public class BizDict extends CommonEntity {
/** id */
@ApiModelProperty("id")
private String id;
/** 父id */
@ApiModelProperty("父级id")
private String parentId;
/** 字典文字 */
@ApiModelProperty("字典文字")
private String dictLabel;
/** 字典值 */
@ApiModelProperty("字典值")
private String dictValue;
/** 分类 */
@ApiModelProperty("分类")
private String category;
/** 排序码 */
@ApiModelProperty("排序码")
private Integer sortCode;
/** 扩展信息 */
@ApiModelProperty("扩展信息")
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
private String extJson;
}

View File

@@ -0,0 +1,47 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.common.base.CommonEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("biz_product")
public class BizProduct extends CommonEntity {
@TableId
private String id;
private String title;
private String description;
private String thumbnail;
private String hotStatus;
private String content;
private String detailUrl;
private BigDecimal amount;
private String status;
private int sortCode;
private String remark;
private String extJson;
@TableField(exist = false)
private String categoryId;
}

View File

@@ -0,0 +1,38 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.corewing.app.common.base.CommonEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("biz_product_category")
public class BizProductCategory extends CommonEntity {
@TableId
private String id;
private String parentId;
private String thumbnail;
private String categoryTitle;
private String description;
private String status;
private Integer sortCode;
private String remark;
private String extJson;
@TableField(exist = false)
Page<BizProduct> productPage;
}

View File

@@ -0,0 +1,18 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("biz_product_category_relation")
public class BizProductCategoryRelation {
@TableId
private String id;
private String productId;
private String categoryId;
}

View File

@@ -0,0 +1,52 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.common.base.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.data.annotation.Id;
/**
* 联系消息
*/
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("app_contact_msg")
public class ContactMsg extends BaseEntity {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 咨询人
*/
private String name;
/**
* 咨询类型
*/
private int category;
/**
* 联系方式
*/
private String contact;
/**
* 咨询内容
*/
private String msg;
/**
* 咨询状态
*/
private int status;
}

View File

@@ -66,4 +66,34 @@ public class Feedback implements Serializable {
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
/**
* 用户昵称
*/
@TableField(exist = false)
private String nickName;
/**
* 用户名
*/
@TableField(exist = false)
private String username;
@TableField(exist = false)
private String statusName;
public String getStatusName() {
switch (status) {
case 0:
return "待处理";
case 1:
return "处理中";
case 2:
return "已完成";
case 3:
return "已关闭";
default:
return "";
}
}
}

View File

@@ -0,0 +1,62 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 反馈日志
*/
@Data
@TableName("app_feedback_log")
public class FeedbackLog implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 反馈用户id
*/
private Long userId;
/**
* oss地址
*/
private String ossPath;
/**
* 日志文件大小
*/
private Long logSize;
/**
* 反馈日志内容
*/
private String logContent;
/**
* 日志文件名称
*/
private String logName;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
}

View File

@@ -61,4 +61,20 @@ public class Firmware implements Serializable {
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableField(exist = false)
private String firmwareTypeName;
public String getFirmwareTypeName() {
switch (firmwareType) {
case 1:
return "调参固件";
case 2:
return "AP固件";
case 3:
return "INAV固件";
default:
return "";
}
}
}

View File

@@ -70,6 +70,21 @@ public class ParamsCenter implements Serializable {
*/
private Integer downloadCount;
/**
* 状态
*/
private String status;
/**
* 审核状态
*/
private String auditStatus;
/**
* 失败原因
*/
private String auditErrorMsg;
/**
* 创建时间
*/
@@ -79,6 +94,6 @@ public class ParamsCenter implements Serializable {
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,48 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.common.base.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 隐私政策实体
*/
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("app_privacy_policy")
public class PrivacyPolicy extends BaseEntity {
/**
* 隐私政策id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 隐私政策名称
*/
private String title;
/**
* 隐私政策内容
*/
private String content;
/**
* 是否显示
*/
private Integer visible;
/**
* 排序
*/
private Integer sort;
/**
* 类型
*/
private Integer category;
}

View File

@@ -0,0 +1,80 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.dto.TrajectoryData;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Data
@TableName("app_replay_session")
public class ReplaySession {
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String syncId;
/**
* 用户id
*/
private Long userId;
/**
* 名称
*/
private String name;
/**
* oss地址
*/
private String ossPath;
/**
* 描述
*/
private String description;
/**
* 开始时间戳
*/
private Long startTime;
/**
* 结束时间戳
*/
private Long endTime;
/**
* 持续时间
*/
private Long duration;
/**
* 数据点
*/
private Long dataCount;
/**
* 创建时间
*/
private Date createdAt;
/**
* 更新时间
*/
private Date updatedAt;
/**
* 轨迹数据点
*/
@TableField(exist = false)
List<TrajectoryData> trajectoryDataList;
}

View File

@@ -0,0 +1,57 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.common.base.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("sys_menu")
public class SysMenu extends BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 菜单id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 菜单名称
*/
private String menuName;
/**
* 菜单地址
*/
private String menuUrl;
/**
* 菜单图标
*/
private String menuIcon;
/**
* 菜单分类
*/
private String menuCategory;
/**
* 是否隐藏
*/
private boolean visible;
/**
* 排序
*/
private int sort;
}

View File

@@ -0,0 +1,31 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.corewing.app.common.base.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("sys_option")
public class SysOption extends BaseEntity {
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 键名
*/
private String key;
/**
* 键值
*/
private String value;
}

View File

@@ -1,12 +1,11 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
/**
@@ -39,6 +38,11 @@ public class Tutorial implements Serializable {
*/
private String content;
/**
* 知识库地址
*/
private String knowledgeUrl;
/**
* 查看次数
*/
@@ -62,12 +66,23 @@ public class Tutorial implements Serializable {
/**
* 创建时间
*/
private Date createTime;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新时间
*/
private Date updateTime;
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
/**
* 教程分类id
*/
@TableField(exist = false)
private Long categoryId;
@TableField(exist = false)
private String categoryName;
}

View File

@@ -1,13 +1,13 @@
package com.corewing.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
/**
* 教程分类
@@ -65,11 +65,19 @@ public class TutorialCategory implements Serializable {
/**
* 创建时间
*/
private Date createTime;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新时间
*/
private Date updateTime;
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
public static final String typeCategory = "category";
public static final String typeTag = "tag";
@TableField(exist = false)
private List<Tutorial> tutorials;
}

View File

@@ -25,6 +25,11 @@ public class User implements Serializable {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 用户昵称
*/
private String nickName;
/**
* 用户名
*/

View File

@@ -0,0 +1,116 @@
package com.corewing.app.handler;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.corewing.app.common.enums.CommonDeleteFlagEnum;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectionException;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;
/**
* MyBatis-Plus 自动填充处理器
* 兼容 Date 和 LocalDateTime 两种时间类型的自动填充
*/
@Component
public class CustomMetaObjectHandler implements MetaObjectHandler {
/** 删除标志 */
private static final String DELETE_FLAG = "deleteFlag";
/** 创建人 */
private static final String CREATE_USER = "createUser";
/** 创建时间 */
private static final String CREATE_TIME = "createTime";
/** 更新人 */
private static final String UPDATE_USER = "updateUser";
/** 更新时间 */
private static final String UPDATE_TIME = "updateTime";
@Override
public void insertFill(MetaObject metaObject) {
try {
//为空则设置deleteFlag
Object deleteFlag = metaObject.getValue(DELETE_FLAG);
if (ObjectUtil.isNull(deleteFlag)) {
setFieldValByName(DELETE_FLAG, EnumUtil.toString(CommonDeleteFlagEnum.NOT_DELETE), metaObject);
}
} catch (ReflectionException ignored) { }
try {
//为空则设置createUser
Object createUser = metaObject.getValue(CREATE_USER);
if (ObjectUtil.isNull(createUser)) {
setFieldValByName(CREATE_USER, this.getUserId(), metaObject);
}
} catch (ReflectionException ignored) { }
try {
// 兼容 Date 和 LocalDateTime 类型的 createTime 填充
fillTimeField(metaObject, CREATE_TIME);
} catch (ReflectionException ignored) { }
}
@Override
public void updateFill(MetaObject metaObject) {
try {
//设置updateUser
setFieldValByName(UPDATE_USER, this.getUserId(), metaObject);
} catch (ReflectionException ignored) {
}
try {
// 兼容 Date 和 LocalDateTime 类型的 updateTime 填充
fillTimeField(metaObject, UPDATE_TIME);
} catch (ReflectionException ignored) {
}
}
/**
* 统一填充时间字段(自动识别 Date/LocalDateTime 类型)
* @param metaObject 元对象
* @param fieldName 时间字段名createTime/updateTime
*/
private void fillTimeField(MetaObject metaObject, String fieldName) {
// 先判断字段是否为空
Object fieldValue = metaObject.getValue(fieldName);
if (ObjectUtil.isNotNull(fieldValue)) {
return; // 字段已有值,不填充
}
// 获取字段的类型,自动匹配填充值类型
Class<?> fieldType = metaObject.getGetterType(fieldName);
if (fieldType == LocalDateTime.class) {
// 字段是 LocalDateTime 类型
setFieldValByName(fieldName, LocalDateTime.now(), metaObject);
} else if (fieldType == Date.class || fieldType == DateTime.class) {
// 字段是 Date/hutool DateTime 类型
setFieldValByName(fieldName, new Date(), metaObject);
}
// 其他类型不处理(避免填充错误)
}
/**
* 获取用户id
*/
private String getUserId() {
try {
String loginId = StpUtil.getLoginIdAsString();
if (ObjectUtil.isNotEmpty(loginId)) {
return loginId;
} else {
return "-1";
}
} catch (Exception e) {
return "-1";
}
}
}

View File

@@ -50,10 +50,10 @@ public class GlobalExceptionHandler {
* 处理其他异常
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
// @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Result<String> handleException(Exception e) {
log.error(e.getMessage());
return Result.error(HttpStatus.INTERNAL_SERVER_ERROR.value(),
I18nUtil.getMessage("error.server.internal", e.getMessage()));
e.getMessage());
}
}

View File

@@ -1,35 +0,0 @@
package com.corewing.app.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* MyBatis-Plus 自动填充处理器
* 用于自动填充创建时间和更新时间
*/
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
/**
* 插入时的填充策略
*/
@Override
public void insertFill(MetaObject metaObject) {
// 自动填充创建时间
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
// 自动填充更新时间
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
/**
* 更新时的填充策略
*/
@Override
public void updateFill(MetaObject metaObject) {
// 自动填充更新时间
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}

View File

@@ -0,0 +1,19 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.corewing.app.dto.AppModel.ModelCategoryListRequest;
import com.corewing.app.dto.AppModel.ModelCategoryPageRequest;
import com.corewing.app.entity.AppModelCategory;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface AppModelCategoryMapper extends BaseMapper<AppModelCategory> {
Page<AppModelCategory> page(Page<AppModelCategory> page, @Param("modelCategoryPageRequest") ModelCategoryPageRequest modelCategoryPageRequest);
List<AppModelCategory> list(@Param("modelCategoryListRequest") ModelCategoryListRequest modelCategoryListRequest);
}

View File

@@ -0,0 +1,9 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.entity.AppModelDownloadLog;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AppModelDownloadLogMapper extends BaseMapper<AppModelDownloadLog> {
}

View File

@@ -0,0 +1,9 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.entity.AppModelFavorite;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AppModelFavoriteMapper extends BaseMapper<AppModelFavorite> {
}

View File

@@ -0,0 +1,9 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.entity.AppModelFile;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AppModelFileMapper extends BaseMapper<AppModelFile> {
}

View File

@@ -0,0 +1,28 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.corewing.app.dto.AppModel.*;
import com.corewing.app.entity.AppModel;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface AppModelMapper extends BaseMapper<AppModel> {
Page<AppModel> page(Page<AppModel> page, @Param("modelPageRequest") ModelPageRequest modelPageRequest);
List<AppModel> list(@Param("modelListRequest") ModelListRequest modelListRequest);
AppModel getModelById(@Param("modelId") String modelId);
List<AppModel> favoriteList(@Param("userId") Long userId, @Param("modelFavoriteListRequest") ModelFavoriteListRequest modelFavoriteListRequest);
Page<AppModel> favoritePage(Page<AppModel> page, @Param("userId") Long userId, @Param("modelFavoritePageRequest") ModelFavoritePageRequest modelFavoritePageRequest);
List<AppModel> downloadLogList(@Param("userId") Long userId, @Param("modelDownloadLogListRequest") ModelDownloadLogListRequest modelDownloadLogListRequest);
Page<AppModel> downloadLogPage(Page<AppModel> page, @Param("userId") Long userId, @Param("modelDownloadLogPageRequest") ModelDownloadLogPageRequest modelDownloadLogPageRequest);
}

View File

@@ -0,0 +1,9 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.entity.AppPublicFirmwarePlane;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AppPublicFirmwarePlaneMapper extends BaseMapper<AppPublicFirmwarePlane> {
}

View File

@@ -0,0 +1,9 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.entity.AppPublicFirmwareVersion;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AppPublicFirmwareVersionMapper extends BaseMapper<AppPublicFirmwareVersion> {
}

View File

@@ -0,0 +1,9 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.entity.AppVersion;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AppVersionMapper extends BaseMapper<AppVersion> {
}

View File

@@ -0,0 +1,9 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.entity.BizDict;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BizDictMapper extends BaseMapper<BizDict> {
}

View File

@@ -0,0 +1,15 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.dto.website.ProductCategoryRequest;
import com.corewing.app.entity.BizProductCategory;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface BizProductCategoryMapper extends BaseMapper<BizProductCategory> {
List<BizProductCategory> list(@Param("productCategoryRequest") ProductCategoryRequest productCategoryRequest);
}

View File

@@ -0,0 +1,14 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.corewing.app.dto.website.ProductPageRequest;
import com.corewing.app.entity.BizProduct;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface BizProductMapper extends BaseMapper<BizProduct> {
Page<BizProduct> page(Page<BizProduct> page, @Param("productPageRequest") ProductPageRequest productPageRequest);
}

View File

@@ -0,0 +1,10 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.entity.ContactMsg;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ContactMsgMapper extends BaseMapper<ContactMsg> {
}

View File

@@ -0,0 +1,10 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.entity.FeedbackLog;
import lombok.Data;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface FeedbackLogMapper extends BaseMapper<FeedbackLog> {
}

View File

@@ -1,8 +1,10 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.corewing.app.entity.Feedback;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 问题反馈 Mapper 接口
@@ -10,4 +12,5 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface FeedbackMapper extends BaseMapper<Feedback> {
Page<Feedback> page(Page<Feedback> page, @Param("feedback") Feedback feedback);
}

View File

@@ -0,0 +1,10 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.entity.PrivacyPolicy;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface PrivacyPolicyMapper extends BaseMapper<PrivacyPolicy> {
}

View File

@@ -0,0 +1,9 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.entity.ReplaySession;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ReplaySessionMapper extends BaseMapper<ReplaySession> {
}

View File

@@ -0,0 +1,9 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.entity.SysMenu;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SysMenuMapper extends BaseMapper<SysMenu> {
}

View File

@@ -0,0 +1,9 @@
package com.corewing.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.corewing.app.entity.SysOption;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SysOptionMapper extends BaseMapper<SysOption> {
}

View File

@@ -13,5 +13,7 @@ import org.apache.ibatis.annotations.Param;
@Mapper
public interface TutorialMapper extends BaseMapper<Tutorial> {
Page<Tutorial> pageList(Page<Tutorial> page, @Param("categoryId") int categoryId, @Param("tutorialTitle") String tutorialTitle, @Param("lang") String lang);
Page<Tutorial> pageList(Page<Tutorial> page, @Param("categoryId") Long categoryId, @Param("tutorialTitle") String tutorialTitle, @Param("lang") String lang);
Page<Tutorial> page(Page<Tutorial> page, @Param("tutorial") Tutorial tutorial);
}

View File

@@ -0,0 +1,29 @@
package com.corewing.app.modules.app;
import com.corewing.app.common.Result;
import com.corewing.app.entity.ContactMsg;
import com.corewing.app.service.ContactMsgService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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 javax.annotation.Resource;
@Api(tags = "官网反馈消息接口")
@RestController
@RequestMapping("/contactMsg")
public class AppContactMsgController {
@Resource
private ContactMsgService contactMsgService;
@ApiOperation("消息保存接口")
@PostMapping("/save")
public Result<String> save(@RequestBody ContactMsg contactMsg) {
return Result.isBool(contactMsgService.save(contactMsg));
}
}

View File

@@ -1,4 +1,4 @@
package com.corewing.app.controller;
package com.corewing.app.modules.app;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -11,6 +11,8 @@ import com.corewing.app.util.DingTalkUtil;
import com.corewing.app.util.I18nUtil;
import com.corewing.app.util.Ip2RegionUtil;
import com.corewing.app.util.IpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@@ -21,15 +23,16 @@ import java.util.List;
/**
* 问题反馈 Controller
*/
@Api(tags = "问题反馈接口")
@RestController
@RequestMapping("/feedback")
public class FeedbackController {
public class AppFeedbackController {
private final FeedbackService feedbackService;
private final DingTalkUtil dingTalkUtil;
private final Ip2RegionUtil ip2RegionUtil;
public FeedbackController(FeedbackService feedbackService, DingTalkUtil dingTalkUtil, Ip2RegionUtil ip2RegionUtil) {
public AppFeedbackController(FeedbackService feedbackService, DingTalkUtil dingTalkUtil, Ip2RegionUtil ip2RegionUtil) {
this.feedbackService = feedbackService;
this.dingTalkUtil = dingTalkUtil;
this.ip2RegionUtil = ip2RegionUtil;
@@ -38,6 +41,7 @@ public class FeedbackController {
/**
* 创建反馈支持匿名提交
*/
@ApiOperation("创建反馈")
@PostMapping
public Result<String> create(@RequestBody FeedbackRequest request, HttpServletRequest httpRequest) {
try {
@@ -75,6 +79,7 @@ public class FeedbackController {
/**
* 查询当前用户的反馈列表
*/
@ApiOperation("查询当前用户的反馈列表")
@GetMapping("/my")
public Result<List<Feedback>> getMyFeedbackList() {
try {
@@ -90,6 +95,7 @@ public class FeedbackController {
/**
* 根据ID查询反馈详情
*/
@ApiOperation("根据id查询反馈详情")
@GetMapping("/{id}")
public Result<Feedback> getById(@PathVariable Long id) {
try {
@@ -112,6 +118,7 @@ public class FeedbackController {
* @param feedbackType 问题类型可选
* @param status 状态可选
*/
@ApiOperation("分页查询反馈列表")
@GetMapping("/page")
public Result<IPage<Feedback>> getPageList(
@RequestParam(defaultValue = "1") Long current,
@@ -131,6 +138,7 @@ public class FeedbackController {
/**
* 更新反馈状态
*/
@ApiOperation("更新反馈状态")
@PutMapping("/{id}/status")
public Result<String> updateStatus(@PathVariable Long id, @RequestParam Integer status) {
try {
@@ -147,6 +155,7 @@ public class FeedbackController {
/**
* 删除反馈
*/
@ApiOperation("删除反馈")
@DeleteMapping("/{id}")
public Result<String> delete(@PathVariable Long id) {
try {
@@ -163,6 +172,7 @@ public class FeedbackController {
/**
* 测试钉钉推送
*/
@ApiOperation("测试钉钉推送")
@GetMapping("/test-dingtalk")
public Result<String> testDingTalk() {
try {
@@ -184,6 +194,7 @@ public class FeedbackController {
/**
* 发送反馈信息到钉钉
*/
@ApiOperation("发送反馈信息到钉钉")
private void sendFeedbackToDingTalk(Feedback feedback, String submitIp, String submitRegion) {
try {
String title = I18nUtil.getMessage("dingtalk.feedback.title");

View File

@@ -0,0 +1,37 @@
package com.corewing.app.modules.app;
import com.corewing.app.common.Result;
import com.corewing.app.entity.FeedbackLog;
import com.corewing.app.service.FeedbackLogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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.annotation.Resource;
/**
* 上传日志接口控制器
*/
@Api(tags = "反馈日志接口")
@RestController
@RequestMapping("/feedback_log")
public class AppFeedbackLogController {
@Resource
private FeedbackLogService feedbackLogService;
/**
* 上传日志
* @param feedbackLog
* @return
*/
@ApiOperation("上传日志")
@PostMapping("/uploadFeedbackLog")
public Result<String> uploadFeedbackLog(MultipartFile file, FeedbackLog feedbackLog) {
return Result.isBool(feedbackLogService.uploadFeedbackLog(file, feedbackLog));
}
}

View File

@@ -1,4 +1,4 @@
package com.corewing.app.controller;
package com.corewing.app.modules.app;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -7,25 +7,29 @@ import com.corewing.app.common.Result;
import com.corewing.app.entity.Firmware;
import com.corewing.app.service.FirmwareService;
import com.corewing.app.util.I18nUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
/**
* 固件 Controller
*/
@Api(tags = "固件接口")
@RestController
@RequestMapping("/firmware")
public class FirmwareController {
public class AppFirmwareController {
private final FirmwareService firmwareService;
public FirmwareController(FirmwareService firmwareService) {
public AppFirmwareController(FirmwareService firmwareService) {
this.firmwareService = firmwareService;
}
/**
* 根据ID查询固件
*/
@ApiOperation("根据id查询固件")
@GetMapping("/{id}")
public Result<Firmware> getById(@PathVariable Long id) {
Firmware firmware = firmwareService.getById(id);
@@ -43,6 +47,7 @@ public class FirmwareController {
* @param firmwareName 固件名称可选
* @param firmwareType 固件类型可选
*/
@ApiOperation("分页查询固件列表")
@GetMapping("/page")
public Result<IPage<Firmware>> page(
@RequestParam(defaultValue = "1") Long current,
@@ -73,6 +78,7 @@ public class FirmwareController {
/**
* 查询所有固件
*/
@ApiOperation("查询所有固件集合")
@GetMapping("/list")
public Result<java.util.List<Firmware>> list() {
java.util.List<Firmware> list = firmwareService.list();
@@ -84,6 +90,7 @@ public class FirmwareController {
*
* @param firmwareType 固件类型
*/
@ApiOperation("根据类型查询固件版本")
@GetMapping("/type/{firmwareType}")
public Result<java.util.List<Firmware>> listByType(@PathVariable Integer firmwareType) {
if (firmwareType == null) {

View File

@@ -0,0 +1,222 @@
package com.corewing.app.modules.app;
import cn.hutool.core.lang.tree.Tree;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.corewing.app.common.Result;
import com.corewing.app.dto.AppModel.*;
import com.corewing.app.entity.AppModel;
import com.corewing.app.entity.AppModelCategory;
import com.corewing.app.service.AppModelCategoryService;
import com.corewing.app.service.AppModelService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
/**
* 模型
*/
@RestController
@RequestMapping("/model")
@Validated
@Api(tags = "模型接口")
public class AppModelController {
@Resource
private AppModelService appModelService;
@Resource
private AppModelCategoryService appModelCategoryService;
/**
* 获取模型分页
* @param modelPageRequest
* @return
*/
@ApiOperation("模型数据分页")
@GetMapping("/page")
public Result<Page<AppModel>> page(ModelPageRequest modelPageRequest) {
return Result.success(appModelService.page(modelPageRequest));
}
/**
* 获取模型集合
* @param modelListRequest
* @return
*/
@ApiOperation("模型数据集合")
@GetMapping("/list")
public Result<List<AppModel>> list(ModelListRequest modelListRequest) {
return Result.success(appModelService.list(modelListRequest));
}
/**
* 获取模型分类分页
* @param modelCategoryPageRequest
* @return
*/
@ApiOperation("模型分类数据分页")
@GetMapping("/category/page")
public Result<Page<AppModelCategory>> categoryPage(ModelCategoryPageRequest modelCategoryPageRequest) {
return Result.success(appModelCategoryService.page(modelCategoryPageRequest));
}
/**
* 获取模型分类集合
* @param modelCategoryListRequest
* @return
*/
@ApiOperation("模型分类数据集合")
@GetMapping("/category/list")
public Result<List<AppModelCategory>> categoryList(ModelCategoryListRequest modelCategoryListRequest) {
return Result.success(appModelCategoryService.list(modelCategoryListRequest));
}
/**
* 获取模型分类树形集合
* @param modelCategoryListRequest
* @return
*/
@ApiOperation("模型分类树形集合")
@GetMapping("/category/tree")
public Result<List<Tree<String>>> categoryTree(ModelCategoryListRequest modelCategoryListRequest) {
return Result.success(appModelCategoryService.tree(modelCategoryListRequest));
}
/**
* 模型收藏
* @param modelFavoriteRequest
* @return
*/
@ApiOperation("收藏模型")
@PostMapping("/favorite")
public Result<String> favorite(@RequestBody @Valid ModelFavoriteRequest modelFavoriteRequest) {
return Result.isBool(appModelService.favorite(modelFavoriteRequest));
}
/**
* 增加模型下载记录
* @param modelDownloadRequest
* @return
*/
@ApiOperation("增加模型下载记录")
@PostMapping("/download")
public Result<String> download(@RequestBody @Valid ModelDownloadRequest modelDownloadRequest) {
return Result.isBool(appModelService.download(modelDownloadRequest));
}
/**
* 点赞模型
* @param modelLikeRequest
* @return
*/
@ApiOperation("点赞模型")
@PostMapping("/like")
public Result<String> like(@RequestBody @Valid ModelLikeRequest modelLikeRequest) {
return Result.isBool(appModelService.like(modelLikeRequest));
}
/**
* 模型详情
* @return
*/
@ApiOperation("模型详情")
@GetMapping("/detail/{modelId}")
public Result<AppModel> detail(@PathVariable String modelId) {
return Result.success(appModelService.detail(modelId));
}
/**
* 创建模型
* @param modelCreateRequest
* @return
*/
@ApiOperation("创建模型")
@PostMapping("/create")
public Result<String> create(@Valid ModelCreateRequest modelCreateRequest) {
return Result.isBool(appModelService.create(modelCreateRequest));
}
/**
* 提交模型审核
* @param modelIdRequest
* @return
*/
@ApiOperation("提交模型审核")
@PostMapping("/audit")
public Result<String> audit(@RequestBody @Valid ModelIdRequest modelIdRequest) {
return Result.isBool(appModelService.audit(modelIdRequest));
}
/**
* 获取收藏列表
* @param modelFavoriteListRequest
* @return
*/
@ApiOperation("收藏模型列表")
@GetMapping("/favorite/list")
public Result<List<AppModel>> favoriteList(ModelFavoriteListRequest modelFavoriteListRequest) {
return Result.success(appModelService.favoriteList(modelFavoriteListRequest));
}
/**
* 获取收藏分页列表
* @param modelFavoritePageRequest
* @return
*/
@ApiOperation("收藏模型分页列表")
@GetMapping("/favorite/page")
public Result<Page<AppModel>> favoritePage(ModelFavoritePageRequest modelFavoritePageRequest) {
return Result.success(appModelService.favoritePage(modelFavoritePageRequest));
}
/**
* 模型下架
* @param modelIdRequest
* @return
*/
@ApiOperation("模型下架")
@PostMapping("/delisted")
public Result<String> delisted(@RequestBody @Valid ModelIdRequest modelIdRequest) {
return Result.isBool(appModelService.delisted(modelIdRequest));
}
/**
* 模型下载记录列表
* @param modelDownloadLogListRequest
* @return
*/
@ApiOperation("模型下载记录列表")
@GetMapping("/download_log/list")
public Result<List<AppModel>> downloadLogList(ModelDownloadLogListRequest modelDownloadLogListRequest) {
return Result.success(appModelService.downloadLogList(modelDownloadLogListRequest));
}
/**
* 模型下载记录分页列表
* @param modelDownloadLogPageRequest
* @return
*/
@ApiOperation("模型下载记录分页列表")
@GetMapping("/download_log/page")
public Result<Page<AppModel>> downloadLogPage(ModelDownloadLogPageRequest modelDownloadLogPageRequest) {
return Result.success(appModelService.downloadLogPage(modelDownloadLogPageRequest));
}
/**
* 删除模型
* @return
*/
@ApiOperation("删除模型")
@DeleteMapping("/delete/{id}")
public Result<String> delete(@PathVariable String id) {
return Result.isBool(appModelService.delete(id));
}
}

View File

@@ -1,4 +1,4 @@
package com.corewing.app.controller;
package com.corewing.app.modules.app;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -10,6 +10,8 @@ import com.corewing.app.entity.ParamsCenter;
import com.corewing.app.service.ParamsCenterService;
import com.corewing.app.util.I18nUtil;
import com.corewing.app.vo.ParamsCenterVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@@ -18,19 +20,21 @@ import java.util.List;
/**
* 参数配置中心 Controller
*/
@Api(tags = "参数配置中心接口")
@RestController
@RequestMapping("/params")
public class ParamsCenterController {
public class AppParamsCenterController {
private final ParamsCenterService paramsService;
public ParamsCenterController(ParamsCenterService paramsService) {
public AppParamsCenterController(ParamsCenterService paramsService) {
this.paramsService = paramsService;
}
/**
* 创建参数配置
*/
@ApiOperation("创建参数配置接口")
@PostMapping
public Result<String> create(@Valid @RequestBody CreateParamRequest request) {
try {
@@ -44,6 +48,8 @@ public class ParamsCenterController {
params.setFcModel(request.getFcModel());
params.setFcType(request.getFcType());
params.setParamVersion(request.getParamVersion());
params.setStatus("1");
params.setAuditStatus("0");
params.setParamDetail(request.getParamDetail());
params.setDownloadCount(0); // 初始化下载次数为0
@@ -60,6 +66,7 @@ public class ParamsCenterController {
/**
* 更新参数配置
*/
@ApiOperation("更新参数配置接口")
@PutMapping
public Result<String> update(@Valid @RequestBody UpdateParamRequest request) {
try {
@@ -97,6 +104,7 @@ public class ParamsCenterController {
/**
* 删除参数配置
*/
@ApiOperation("根据id删除参数配置")
@DeleteMapping("/{id}")
public Result<String> delete(@PathVariable Long id) {
try {
@@ -124,6 +132,7 @@ public class ParamsCenterController {
/**
* 根据ID查询参数配置
*/
@ApiOperation("根据id查询参数配置")
@GetMapping("/{id}")
public Result<ParamsCenterVO> getById(@PathVariable Long id) {
try {
@@ -144,8 +153,9 @@ public class ParamsCenterController {
}
/**
* 查询所有参数列表公开接口支持飞控型号过滤
* 查询所有公共参数列表公开接口支持飞控型号过滤
*/
@ApiOperation("获取所有公共参数集合")
@GetMapping("/all/list")
public Result<List<ParamsCenterVO>> listAll(@RequestParam(required = false) String fcModel) {
try {
@@ -159,6 +169,7 @@ public class ParamsCenterController {
/**
* 查询当前用户的参数列表支持飞控型号过滤
*/
@ApiOperation("获取当前用户的参数列表")
@GetMapping("/my/list")
public Result<List<ParamsCenterVO>> listMy(@RequestParam(required = false) String fcModel) {
try {
@@ -173,6 +184,7 @@ public class ParamsCenterController {
/**
* 分页查询所有参数列表公开接口支持飞控型号过滤
*/
@ApiOperation("分页查询所有公共参数集合")
@GetMapping("/all/page")
public Result<IPage<ParamsCenterVO>> pageAll(
@RequestParam(defaultValue = "1") Long current,
@@ -190,6 +202,7 @@ public class ParamsCenterController {
/**
* 分页查询当前用户的参数列表支持飞控型号过滤
*/
@ApiOperation("分页查询当前用户参数列表")
@GetMapping("/my/page")
public Result<IPage<ParamsCenterVO>> pageMy(
@RequestParam(defaultValue = "1") Long current,
@@ -208,6 +221,7 @@ public class ParamsCenterController {
/**
* 增加下载次数
*/
@ApiOperation("增加参数中心下载次数")
@PostMapping("/{id}/download")
public Result<String> incrementDownloadCount(@PathVariable Long id) {
try {
@@ -230,4 +244,33 @@ public class ParamsCenterController {
return Result.error(e.getMessage());
}
}
/**
* 提交审核
* @param id
* @return
*/
@ApiOperation("发布公共参数提交审核")
@GetMapping("/review/{id}")
public Result<String> review(@PathVariable Long id) {
try {
ParamsCenter params = paramsService.getById(id);
if (params == null) {
return Result.error(I18nUtil.getMessage("params.not.found"));
}
// 提交审核
ParamsCenter updateParams = new ParamsCenter();
updateParams.setId(id);
updateParams.setAuditStatus("1");
updateParams.setAuditErrorMsg("");
boolean success = paramsService.updateById(updateParams);
if (success) {
return Result.success(I18nUtil.getMessage("params.update.success"));
}
return Result.error(I18nUtil.getMessage("params.update.failed"));
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,58 @@
package com.corewing.app.modules.app;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.corewing.app.common.Result;
import com.corewing.app.entity.PrivacyPolicy;
import com.corewing.app.service.PrivacyPolicyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
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.ResponseBody;
import javax.annotation.Resource;
import java.util.List;
/**
* 隐私政策与协议
*/
@Api(tags = "隐私政策与协议")
@Controller
@RequestMapping("/privacy_policy")
public class AppPrivacyPolicyController {
@Resource
private PrivacyPolicyService privacyPolicyService;
/**
* 隐私政策列表
* @return
*/
@ApiOperation("隐私政策列表")
@GetMapping("/view_list/{lang}")
public String viewList(@PathVariable String lang, ModelMap modelMap) {
List<PrivacyPolicy> list = privacyPolicyService.list();
modelMap.put("list", list);
// 获取最新更新时间
modelMap.put("lastUpdateTime", privacyPolicyService.getLastUpdateTime());
return "privacyPolicy/index";
}
/**
* 根据类型获取集合数据
* @param category
* @return
*/
@ApiOperation("根据类型获取集合数据")
@GetMapping("/getListByCategory/{category}")
@ResponseBody
public Result<PrivacyPolicy> getListByCategory(@PathVariable Integer category) {
LambdaQueryWrapper<PrivacyPolicy> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(PrivacyPolicy::getCategory, category);
return Result.success(privacyPolicyService.getOne(wrapper));
}
}

View File

@@ -0,0 +1,66 @@
package com.corewing.app.modules.app;
import com.corewing.app.common.Result;
import com.corewing.app.dto.publicFirmware.PublicBoardTypeListRequest;
import com.corewing.app.dto.publicFirmware.PublicFirmwareListRequest;
import com.corewing.app.dto.publicFirmware.PublicFirmwareVersionListRequest;
import com.corewing.app.entity.AppPublicFirmwarePlane;
import com.corewing.app.entity.AppPublicFirmwareVersion;
import com.corewing.app.entity.BizDict;
import com.corewing.app.service.AppPublicFirmwarePlaneService;
import com.corewing.app.service.AppPublicFirmwareVersionService;
import com.corewing.app.service.BizDictService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@Api(tags = "公共固件接口")
@RestController
@RequestMapping("/public_firmware")
public class AppPublicFirmwareController {
@Resource
private BizDictService bizDictService;
@Resource
private AppPublicFirmwareVersionService appPublicFirmwareVersionService;
@Resource
private AppPublicFirmwarePlaneService appPublicFirmwarePlaneService;
@ApiOperation("获取固件类型集合")
@GetMapping("/getFirmwareTypeAll")
public Result<List<BizDict>> getFirmwareTypeAll() {
return Result.success(bizDictService.getDataListByKey());
}
@ApiOperation("根据固件类型获取版本集合")
@GetMapping("/getVersionList")
public Result<List<AppPublicFirmwareVersion>> getVersionList(PublicFirmwareVersionListRequest publicFirmwareVersionListRequest) {
return Result.success(appPublicFirmwareVersionService.getVersionList(publicFirmwareVersionListRequest));
}
@ApiOperation("根据固件类型&版本获取板载类型集合")
@GetMapping("/getBoardTypeList")
public Result<List<String>> getBoardTypeList(PublicBoardTypeListRequest publicBoardTypeListRequest) {
return Result.success(appPublicFirmwarePlaneService.getBoardTypeList(publicBoardTypeListRequest));
}
@ApiOperation("根据固件类型&版本&板载获取固件集合")
@GetMapping("/getFirmwareList")
public Result<List<AppPublicFirmwarePlane>> getFirmwareList(PublicFirmwareListRequest publicFirmwareListRequest) {
return Result.success(appPublicFirmwarePlaneService.getFirmwareList(publicFirmwareListRequest));
}
}

View File

@@ -0,0 +1,55 @@
package com.corewing.app.modules.app;
import cn.dev33.satoken.stp.StpUtil;
import com.corewing.app.common.Result;
import com.corewing.app.dto.uploadReplaySessionRequest;
import com.corewing.app.entity.ReplaySession;
import com.corewing.app.service.ReplaySessionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@Api(tags = "飞行记录接口")
@RestController
@RequestMapping("/replay-session")
public class AppReplaySessionController {
@Resource
private ReplaySessionService replaySessionService;
/**
* 获取飞行记录
* @return
*/
@ApiOperation("获取当前用户飞行记录")
@GetMapping("/getReplayList")
public Result<List<ReplaySession>> getReplayList() {
return Result.success(replaySessionService.getReplayList(StpUtil.getLoginId()));
}
/**
* 上传飞行记录
* @param uploadReplaySessionRequests
* @return
*/
@ApiOperation("上传飞行记录")
@PostMapping("/uploadReplaySession")
public Result<Boolean> uploadReplaySession(@RequestBody List<uploadReplaySessionRequest> uploadReplaySessionRequests) {
return Result.isBool(replaySessionService.uploadReplaySession(uploadReplaySessionRequests));
}
/**
* 根据同步id删除数据
* @param syncId
* @return
*/
@ApiOperation("根据同步id删除飞行记录")
@DeleteMapping("/deleteReplaySession/{syncId}")
public Result<Boolean> deleteReplaySession(@PathVariable String syncId) {
return Result.isBool(replaySessionService.deleteReplaySession(syncId));
}
}

View File

@@ -1,4 +1,4 @@
package com.corewing.app.controller;
package com.corewing.app.modules.app;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -9,36 +9,55 @@ import com.corewing.app.entity.TutorialCategory;
import com.corewing.app.service.TutorialCategoryService;
import com.corewing.app.service.TutorialService;
import com.corewing.app.util.I18nUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
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 org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 教程接口
*/
@Api(tags = "教程接口")
@RequestMapping("/tutorial")
@RestController
@Controller
@Slf4j
public class TutorialController {
public class AppTutorialController {
private final TutorialService tutorialService;
private final TutorialCategoryService tutorialCategoryService;
public TutorialController(TutorialService tutorialService, TutorialCategoryService tutorialCategoryService) {
public AppTutorialController(TutorialService tutorialService, TutorialCategoryService tutorialCategoryService) {
this.tutorialService = tutorialService;
this.tutorialCategoryService = tutorialCategoryService;
}
/**
* 跳转到界面查看教程详情
* @param tutorialId 教程id
* @param model 数据模型
* @return 详情页
*/
@ApiOperation("跳转到界面查看教程详情")
@GetMapping("/viewDetail/{tutorialId}")
public String viewDetail(@PathVariable Long tutorialId, ModelMap model) {
Tutorial tutorial = tutorialService.getById(tutorialId);
model.put("tutorial", tutorial);
return "tutorial/viewDetail";
}
/**
* 添加查看次数
* @param tutorialId 教程id
* @return
*/
@ApiOperation("添加查看次数")
@GetMapping("/addViewCount")
@ResponseBody
public Result<String> addViewCount(@RequestParam Long tutorialId) {
Tutorial tutorial = tutorialService.getById(tutorialId);
if(tutorial == null) {
@@ -55,7 +74,9 @@ public class TutorialController {
* @param firstStatus 置首状态选填
*
*/
@ApiOperation("分类查询集合")
@GetMapping("/category")
@ResponseBody
public Result<List<TutorialCategory>> category(
@RequestParam(required = false, defaultValue = "0") Integer firstStatus
) {
@@ -76,20 +97,21 @@ public class TutorialController {
* @param tutorialTitle 教程标题选填
*
*/
@ApiOperation("分页查询教程列表")
@GetMapping("/page")
@ResponseBody
public Result<IPage<Tutorial>> getPageList(
@RequestParam(defaultValue = "1") Long current,
@RequestParam(defaultValue = "10") Long size,
@RequestParam(required = false, defaultValue = "0") Integer categoryId,
@RequestParam(required = false, defaultValue = "0") Long categoryId,
@RequestParam(required = false) String tutorialTitle) {
try {
Page<Tutorial> page = new Page<>(current, size);
IPage<Tutorial> pageResult = tutorialService.pageList(page, categoryId, tutorialTitle, I18nUtil.getCurrentLocale().getLanguage());
Page<Tutorial> pageResult = tutorialService.pageList(page, categoryId, tutorialTitle, I18nUtil.getCurrentLocale().getLanguage());
return Result.success(pageResult);
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -1,33 +1,34 @@
package com.corewing.app.controller;
package com.corewing.app.modules.app;
import cn.dev33.satoken.stp.StpUtil;
import com.corewing.app.common.Result;
import com.corewing.app.dto.LoginRequest;
import com.corewing.app.dto.RegisterRequest;
import com.corewing.app.dto.SendCodeRequest;
import com.corewing.app.dto.UpdatePasswordRequest;
import com.corewing.app.dto.*;
import com.corewing.app.entity.User;
import com.corewing.app.service.UserService;
import com.corewing.app.service.VerifyCodeService;
import com.corewing.app.util.I18nUtil;
import com.corewing.app.util.IpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
/**
* 应用用户 Controller
*/
@Api(tags = "用户接口")
@RestController
@RequestMapping("/user")
public class UserController {
public class AppUserController {
private final UserService userService;
private final VerifyCodeService verifyCodeService;
public UserController(UserService userService, VerifyCodeService verifyCodeService) {
public AppUserController(UserService userService, VerifyCodeService verifyCodeService) {
this.userService = userService;
this.verifyCodeService = verifyCodeService;
}
@@ -35,6 +36,7 @@ public class UserController {
/**
* 发送验证码
*/
@ApiOperation("发送验证码接口")
@PostMapping("/sendCode")
public Result<String> sendCode(@RequestBody SendCodeRequest request) {
try {
@@ -51,6 +53,7 @@ public class UserController {
/**
* 用户登录支持用户名/邮箱/手机号
*/
@ApiOperation("用户登录接口")
@PostMapping("/login")
public Result<Map<String, Object>> login(@RequestBody LoginRequest request, HttpServletRequest httpRequest) {
try {
@@ -75,6 +78,7 @@ public class UserController {
/**
* 用户注册需要验证码
*/
@ApiOperation("用户注册接口")
@PostMapping("/register")
public Result<String> register(@RequestBody RegisterRequest request, HttpServletRequest httpRequest) {
try {
@@ -97,6 +101,7 @@ public class UserController {
/**
* 用户登出
*/
@ApiOperation("用户登出接口")
@PostMapping("/logout")
public Result<String> logout() {
StpUtil.logout();
@@ -106,6 +111,7 @@ public class UserController {
/**
* 获取当前登录用户信息
*/
@ApiOperation("获取当前登录用户信息")
@GetMapping("/info")
public Result<User> getUserInfo() {
Long userId = StpUtil.getLoginIdAsLong();
@@ -118,6 +124,7 @@ public class UserController {
/**
* 根据ID查询用户
*/
@ApiOperation("根据id查询用户")
@GetMapping("/{id}")
public Result<User> getById(@PathVariable Long id) {
User user = userService.getById(id);
@@ -132,11 +139,13 @@ public class UserController {
/**
* 更新用户信息
*/
@PutMapping
@ApiOperation("更新用户信息")
@PutMapping("/update")
public Result<String> update(@RequestBody User user) {
Long userId = StpUtil.getLoginIdAsLong();
user.setId(userId);
// 不允许通过此接口修改密码
user.setPassword(null);
boolean success = userService.updateById(user);
if (success) {
return Result.success(I18nUtil.getMessage("user.update.success"));
@@ -147,6 +156,7 @@ public class UserController {
/**
* 修改密码
*/
@ApiOperation("用户修改密码")
@PutMapping("/password")
public Result<String> updatePassword(@RequestBody UpdatePasswordRequest request) {
try {
@@ -173,4 +183,57 @@ public class UserController {
return Result.error(e.getMessage());
}
}
/**
* 忘记密码
* @param request
* @return
*/
@ApiOperation("忘记密码")
@PutMapping("/forgetPassword")
public Result<String> forgetPassword(@RequestBody ForgetPasswordRequest request) {
return Result.isBool(userService.forgetPassword(request));
}
/**
* 验证码登录
* @return
*/
@ApiOperation("验证码登录")
@PostMapping("/codeLogin")
public Result<Map<String, Object>> codeLogin(@RequestBody CodeLoginRequest codeLoginRequest, HttpServletRequest request) {
String token = userService.codeLogin(codeLoginRequest);
// 更新登录IP和归属地
User user = userService.getByAccount(codeLoginRequest.getAccount());
String loginIp = IpUtil.getClientIp(request);
userService.updateLoginInfo(user.getId(), loginIp);
Map<String, Object> data = new HashMap<>();
data.put("token", token);
data.put("userId", user.getId());
data.put("username", user.getUsername());
return Result.success(I18nUtil.getMessage("user.login.success"), data);
}
/**
* 注销用户
* @param logoffRequest
* @return
*/
@ApiOperation("注销用户")
@DeleteMapping("/delete")
public Result<String> logoff(@RequestBody @Valid LogoffRequest logoffRequest) {
return Result.isBool(userService.logoff(logoffRequest));
}
/**
* 注销发送验证码
* @return
*/
@ApiOperation("发送注销验证码")
@PostMapping("/delete/sendCode")
public Result<Map<String, String>> deleteSendCode() {
return userService.deleteSendCode();
}
}

View File

@@ -0,0 +1,42 @@
package com.corewing.app.modules.app;
import com.corewing.app.common.Result;
import com.corewing.app.dto.CheckVersionRequest;
import com.corewing.app.entity.AppVersion;
import com.corewing.app.service.AppVersionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* app升级校验接口
*/
@Api(tags = "APP版本接口")
@RestController
@RequestMapping("/app_version")
public class AppVersionController {
@Resource
private AppVersionService appVersionService;
/**
* 校验是否存在新版本
* @param checkVersionRequest
* @return
*/
@ApiOperation("校验是否有新版本")
@GetMapping("/checkUpdate")
public Result<Object> checkUpdate(CheckVersionRequest checkVersionRequest) {
AppVersion version = appVersionService.getNewAppVersion(checkVersionRequest);
if(version == null) {
return Result.error("暂无新版本");
}
return Result.success(version);
}
}

View File

@@ -0,0 +1,18 @@
package com.corewing.app.modules.directive;
import com.corewing.app.service.SysOptionService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service("option")
public class SysOptionDirective {
@Resource
private SysOptionService sysOptionService;
public String getValue(String key) {
return sysOptionService.getValueByKey(key);
}
}

View File

@@ -0,0 +1,32 @@
package com.corewing.app.modules.website;
import com.corewing.app.common.Result;
import com.corewing.app.entity.AppVersion;
import com.corewing.app.service.AppVersionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 获取最新的APP版本
*/
@Api(tags = "官网APP版本")
@RestController
@RequestMapping("/api/app")
public class WebsiteAppVersionController {
@Resource
private AppVersionService appVersionService;
@ApiOperation("获取最新APP版本")
@GetMapping("/getAppVersion")
public Result<AppVersion> getAppVersion() {
return Result.success(appVersionService.getAppVersion());
}
}

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