修改百度地图AK

This commit is contained in:
xuqiuyun
2025-11-04 09:38:19 +08:00
parent 4b6d14a6ec
commit eacb0453dd
52 changed files with 3865 additions and 65 deletions

78
.cursor/rules/.gitignore vendored Normal file
View File

@@ -0,0 +1,78 @@
# 操作系统生成的文件
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# IDE和编辑器
## Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
.history/
## Cursor
.cursor/
*.cursor-project
## IntelliJ IDEA
.idea/
*.iml
*.iws
*.ipr
.idea_modules/
out/
atlassian-ide-plugin.xml
# 依赖包目录
node_modules/
jspm_packages/
bower_components/
# 构建输出
dist/
build/
out/
*.min.js
*.min.css
# 日志
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# 环境变量和秘钥
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
.env.*.local
*.pem
# 测试覆盖率
coverage/
.nyc_output/
# 临时文件
tmp/
temp/
*.swp
*.swo
# 缓存目录
.npm
.eslintcache
.stylelintcache
.cache/
.parcel-cache/
.history/

133
.cursor/rules/README.md Normal file
View File

@@ -0,0 +1,133 @@
# Cursor Rules 规则汇总
本项目用于收集、整理和标准化 Cursor Rules 规则文件,提供多种编程语言和框架的规则支持,使开发者能够更有效地利用 Cursor 进行开发工作。
## Cursor Rules 最佳实践
文章教程:
[Cursor Rules 的一次全面总结,希望能够帮助到你!](https://mp.weixin.qq.com/s/l8r2lJlEv5fKWJRSsSd1kQ)
[Cursor 0.49.x 自动化生成 Project Rules 实用指南](https://mp.weixin.qq.com/s/1yTkzYzOFjty1D0gtYHuHA)
[Cursor Rules 进阶指南:打造企业级多语言开发规范](https://mp.weixin.qq.com/s/rfanrMtMMuyUTwsDYmlxSg)
[Cursor Rules 最佳实践总结](https://mp.weixin.qq.com/s/-J_LwfwH9rmFy4dzEy0RXg)
视频教程:
https://www.bilibili.com/video/BV1S3VhzpEqL/
### 1、通用规则层
这些规则始终生效,为所有代码提供基础规范:
- **core.mdc** - 核心开发原则和响应语言
- **teck-stack.mdc** - 技术栈定义和官方文档链接
- **project-structure.mdc** - 项目结构和文件组织规范
- **general.mdc** - 通用编程规则(后续将移除)
### 2、编程语言层
根据文件扩展名自动应用的语言特定规范:
- **Python** (python.mdc)
- **Java** (java.mdc)
- **TypeScript** (typescript.mdc)
- **Go** (golang.mdc)
- **C++** (c++.mdc)
- **CSS** (css.mdc)
- **WXML** (wxml.mdc) - 微信小程序标记语言
- **WXSS** (wxss.mdc) - 微信小程序样式表
- **Kotlin** (kotlin.mdc)
### 3、框架层
根据文件扩展名自动应用规范或者AI可根据上下文自动判断并请求的框架特定规范
#### 前端框架
- **React** (react.mdc) - React 应用开发
- **Vue.js** (vuejs.mdc) - Vue.js 应用开发
- **Next.js** (nextjs.mdc) - React 全栈框架
- **Tailwind CSS** (tailwind.mdc) - 实用优先的 CSS 框架
#### 后端框架
- **Django** (django.mdc) - Python Web 框架
- **Flask** (flask.mdc) - Python 轻量级 Web 框架
- **FastAPI** (fastapi.mdc) - Python 现代 API 框架
- **Spring Boot** (springboot.mdc) - Java 企业级框架
#### 移动开发框架
- **Flutter** (flutter.mdc) - 跨平台移动应用开发
- **SwiftUI** (swiftui.mdc) - iOS 原生 UI 框架
- **React Native** (react-native.mdc) - 跨平台移动应用开发
- **Android**(android.mdc) - Android 框架开发规范
### 4、其他工具层可选非必需
需要用户明确请求的工具和流程规范,使用 `@` 引入对应的规则。
- **Git相关规则** (git.mdc)
- **Git Flow工作流规则** (gitflow.mdc)
- **文档编写规则** (document.mdc)
## 使用方法
1. 克隆本仓库
2. 浏览相应语言和框架的规则
3. 将适用的规则应用到您的项目中
4. 贡献您自己的规则回馈社区
## 项目结构
```
cursor-rules/
├── base/ # 基础规则层(通用规则)
│ ├── core.mdc # 核心开发原则和响应语言
│ ├── tech-stack.mdc # 技术栈定义和官方文档链接
│ ├── project-structure.mdc # 项目结构和文件组织规范
│ └── general.mdc # 通用编程规则
├── languages/ # 编程语言特定规则
│ ├── c++.mdc # C++语言规则
│ ├── css.mdc # CSS样式规则
│ ├── golang.mdc # Go语言规则
│ ├── java.mdc # Java语言规则
│ ├── kotlin.mdc # Kotlin语言规则
│ ├── python.mdc # Python语言规则
│ ├── typescript.mdc # TypeScript语言规则
│ ├── wxml.mdc # 微信小程序标记语言规则
│ └── wxss.mdc # 微信小程序样式表规则
├── frameworks/ # 框架相关规则
│ ├── # 前端框架
│ ├── nextjs.mdc # Next.js框架规则
│ ├── react.mdc # React框架规则
│ ├── react-native.mdc # React Native框架规则
│ ├── vuejs.mdc # Vue.js框架规则
│ ├── tailwind.mdc # Tailwind CSS规则
│ ├── # 后端框架
│ ├── django.mdc # Django框架规则
│ ├── fastapi.mdc # FastAPI框架规则
│ ├── flask.mdc # Flask框架规则
│ ├── springboot.mdc # Spring Boot框架规则
│ ├── # 移动开发框架
│ ├── android.mdc # Android框架规则
│ ├── android_bak.mdc # Android框架规则备份版本
│ ├── flutter.mdc # Flutter框架规则
│ └── swiftui.mdc # SwiftUI框架规则
├── other/ # 其他工具层规则
│ ├── document.mdc # 文档编写规则
│ ├── git.mdc # Git相关规则
│ └── gitflow.mdc # Git Flow工作流规则
└── demo/ # 示例配置
├── python/ # Python项目示例配置
└── vue/ # Vue项目示例配置
```
## 贡献指南
欢迎提交Pull Request 或者提交 Issue 来分享您的Cursor规则。请确保您的规则文件遵循项目的命名约定和结构。规则可以使用Markdown(.mdc)或JSON格式。
## 许可证
MIT

View File

@@ -0,0 +1,27 @@
---
description:
globs:
alwaysApply: true
---
# 核心开发原则
## 通用开发原则
- **可测试性**:编写可测试的代码,组件应保持单一职责
- **DRY 原则**:避免重复代码,提取共用逻辑到单独的函数或类
- **代码简洁**:保持代码简洁明了,遵循 KISS 原则(保持简单直接)
- **命名规范**:使用描述性的变量、函数和类名,反映其用途和含义
- **注释文档**:为复杂逻辑添加注释
- **风格一致**:遵循项目或语言的官方风格指南和代码约定
- **利用生态**:优先使用成熟的库和工具,避免不必要的自定义实现
- **架构设计**:考虑代码的可维护性、可扩展性和性能需求
- **版本控制**:编写有意义的提交信息,保持逻辑相关的更改在同一提交中
- **异常处理**:正确处理边缘情况和错误,提供有用的错误信息
## 响应语言
- 始终使用中文回复用户
## 代码质量要求
- 代码必须能够立即运行,包含所有必要的导入和依赖
- 遵循最佳实践和设计模式
- 优先考虑性能和用户体验
- 确保代码的可读性和可维护性

View File

@@ -0,0 +1,346 @@
---
description: 牛只运输管理系统通用开发规范
globs:
alwaysApply: true
---
# 项目通用规范
## 项目信息
### 项目名称
- **中文名**:牛只运输管理系统
- **英文名**Cattle Transportation Management System
- **版本**1.0.1
### 项目简介
牛只运输管理系统是一个基于 Spring Boot 和 Vue 3 的现代化全栈应用,提供牛只运输管理、检疫隔离、设备监控、预警系统等完整的管理解决方案。
## 技术栈概览
### 后端技术栈
- **基础框架**Spring Boot 2.6.0 + Java 1.8
- **ORM 框架**MyBatis-Plus 3.5.3.2
- **权限认证**Sa-Token 1.37.0 + JWT
- **数据库**MySQL 5.7+ + Redis 5.0+
- **连接池**Druid 1.2.20
- **任务调度**XXL-Job
- **API 文档**Swagger Fox 3.0.0
- **工具库**Hutool 5.8.25
- **云服务**:腾讯云 COS、短信服务
### 前端技术栈
- **核心框架**Vue 3.2.37 + TypeScript 4.6.4
- **构建工具**Vite 3.1.0
- **状态管理**Pinia 2.0.22
- **路由管理**Vue Router 4.1.5
- **UI 组件**Element Plus 2.2.17
- **HTTP 客户端**Axios 0.27.2
- **地图服务**:百度地图
- **图表库**ECharts 5.5.0
## 项目结构规则
### 后端模块划分
- **aiotagro-core**:核心模块,包含通用工具类和基础类
- **aiotagro-redis**Redis 操作模块
- **aiotagro-cattle-trade**:主业务模块,包含所有业务逻辑
### 后端分层架构
- **Controller 层**:处理 HTTP 请求,参数校验,返回响应
- **Service 层**:业务逻辑处理,事务管理
- **Mapper 层**:数据访问层,执行 SQL 操作
- **Entity 层**:数据库实体映射
- **DTO 层**:数据传输对象,接收前端参数
- **VO 层**:视图对象,返回给前端的数据
### 前端模块划分
- **api/**API 接口定义,按业务模块划分
- **components/**:公共组件
- **views/**:页面组件
- **store/**Pinia 状态管理
- **router/**:路由配置
- **utils/**:工具函数
## 通用开发原则
### 代码质量
- **可测试性**:编写可测试的代码,组件应保持单一职责
- **DRY 原则**:避免重复代码,提取共用逻辑到单独的函数或类
- **代码简洁**:保持代码简洁明了,遵循 KISS 原则Keep It Simple, Stupid
- **命名规范**:使用描述性的变量、函数和类名,反映其用途和含义
- **注释文档**:为复杂逻辑添加注释,公共 API 编写文档注释
- **风格一致**:遵循项目或语言的官方风格指南和代码约定
### 架构设计
- **利用生态**:优先使用成熟的库和工具,避免不必要的自定义实现
- **架构设计**:考虑代码的可维护性、可扩展性和性能需求
- **异常处理**:正确处理边缘情况和错误,提供有用的错误信息
- **分层解耦**:严格遵守分层架构,避免跨层调用
- **接口编程**:面向接口编程,依赖抽象而非具体实现
### 版本控制
- **提交信息**:编写有意义的提交信息,保持逻辑相关的更改在同一提交中
- **分支管理**:使用 Git Flow 工作流main/master、develop、feature、hotfix
- **代码审查**:提交前进行代码自查,重要变更需要 Code Review
## 响应语言
- **始终使用中文回复用户**
- 代码注释使用中文
- 文档使用中文
- 变量和函数名使用英文
## 代码规范
### 后端代码规范Java
- **命名约定**
- 类名PascalCase如 `DeliveryController`
- 方法名camelCase如 `findUserById`
- 常量UPPER_CASE如 `MAX_RETRY_ATTEMPTS`
- 包名:小写,按功能模块划分
- **注释规范**
- 类注释:说明类的用途、作者、创建日期
- 方法注释JavaDoc 格式,说明参数、返回值、异常
- 复杂逻辑:添加行内注释解释
- **异常处理**
- 使用 Spring 全局异常处理器统一处理异常
- 业务异常使用自定义异常类
- 记录详细的错误日志
- **事务管理**
- 在 Service 层使用 `@Transactional` 注解
- 合理设置事务传播行为和隔离级别
- 只读操作使用 `readOnly = true`
### 前端代码规范Vue 3 + TypeScript
- **命名约定**
- 组件文件PascalCase 或 camelCase
- 变量和函数camelCase
- 常量UPPER_CASE
- 类型和接口PascalCase
- **组件规范**
- 使用 Vue 3 Composition API
- 组件保持单一职责
- Props 使用 TypeScript 类型定义
- 合理使用响应式数据ref、reactive
- **代码格式**
- 使用 ESLint 进行代码检查
- 使用 Prettier 进行代码格式化
- 缩进4 个空格
- 行宽150 字符
- 语句末尾使用分号
## 数据库规范
### 表命名规范
- 表名:小写,使用下划线分隔(如 `delivery`、`jbq_client_log`
- 字段名:小写,使用下划线分隔(如 `create_time`、`device_id`
- 主键:`id`(整型,自增)
- 外键:`<关联表名>_id`
### 字段规范
- **通用字段**
- `id`主键INT 或 BIGINT自增
- `create_time`创建时间DATETIME
- `update_time`更新时间DATETIME
- `created_by`创建人VARCHAR 或 INT
- `updated_by`更新人VARCHAR 或 INT
- `is_delete`逻辑删除标记TINYINT0-未删除1-已删除)
- **字段类型选择**
- 字符串VARCHAR指定长度或 TEXT超长文本
- 数值INT、BIGINT、DECIMAL精度要求高的数值
- 日期时间DATETIME、TIMESTAMP
- 布尔TINYINT(1)0-false1-true
- **字段约束**
- 合理使用 NOT NULL 约束
- 添加 DEFAULT 默认值
- 添加 COMMENT 注释说明
### 索引规范
- 主键自动创建索引
- 频繁查询的字段添加普通索引
- 多字段组合查询添加联合索引
- 唯一性约束使用唯一索引(如 `uk_license_plate`
### 迁移脚本规范
- 位置:`tradeCattle/aiotagro-cattle-trade/src/main/resources/db/migration/`
- 命名:`alter_<table_name>_<description>.sql`
- 内容:包含 `USE cattletrade;` 和详细注释
- 执行后:注释掉已执行的 DDL 语句,保留作为文档
## API 设计规范
### RESTful API 规范
- **URL 设计**
- 使用名词复数形式(如 `/api/deliveries`
- 避免动词(查询、创建等通过 HTTP 方法区分)
- 层次结构体现资源关系(如 `/api/deliveries/{id}/devices`
- **HTTP 方法**
- GET查询资源
- POST创建资源
- PUT完整更新资源
- PATCH部分更新资源
- DELETE删除资源
- **状态码**
- 200成功
- 201创建成功
- 400请求参数错误
- 401未认证
- 403无权限
- 404资源不存在
- 500服务器错误
### 响应格式
- **统一响应结构**
```json
{
"code": 200,
"msg": "操作成功",
"data": {...}
}
```
- **分页响应**
```json
{
"code": 200,
"msg": "查询成功",
"total": 100,
"rows": [...]
}
```
- **错误响应**
```json
{
"code": 400,
"msg": "参数校验失败:手机号格式不正确"
}
```
## 安全规范
### 认证授权
- 使用 Sa-Token 进行权限认证
- 接口需要添加权限注解(`@SaCheckPermission`
- 敏感接口添加登录检查(`@SaCheckLogin`
- Token 存储在 Redis 中,支持会话管理
### 数据安全
- 密码使用加密存储BCrypt
- 敏感数据传输使用 HTTPS
- SQL 注入防护:使用参数化查询
- XSS 防护:前端输出编码
- 文件上传:限制文件类型和大小
### 日志安全
- 不在日志中输出敏感信息(密码、身份证等)
- 记录关键操作日志(登录、修改、删除)
- 生产环境使用合适的日志级别INFO 或 WARN
## 性能优化规范
### 后端优化
- 使用数据库连接池Druid
- 合理使用缓存Redis
- 避免 N+1 查询问题
- 批量操作使用批处理
- 异步处理耗时操作
### 前端优化
- 组件懒加载
- 路由懒加载
- 图片懒加载
- 合理使用 computed 和 watch
- 避免不必要的响应式数据
### 数据库优化
- 合理使用索引
- 避免全表扫描
- 分页查询大数据量
- 定期清理历史数据
- 读写分离(如有需要)
## 测试规范
### 单元测试
- Service 层编写单元测试
- 测试覆盖率目标60% 以上
- 使用 JUnit 5 + Mockito后端
- 关键业务逻辑必须有单元测试
### 集成测试
- Controller 层编写集成测试
- 测试完整的业务流程
- 使用测试数据库
- 测试前清理数据
### 前端测试
- 工具函数编写单元测试
- 关键组件编写测试
- 使用 Jest + Vue Test Utils
## 日志规范
### 日志级别
- **ERROR**:系统错误,需要立即处理
- **WARN**:警告信息,可能影响系统运行
- **INFO**:重要业务信息,正常流程记录
- **DEBUG**:调试信息,开发环境使用
### 日志内容
- 关键操作日志:谁、在什么时间、做了什么、结果如何
- 异常日志:记录异常堆栈和上下文信息
- 性能日志:记录关键操作的执行时间
- 不记录敏感信息
## 部署规范
### 环境配置
- **开发环境**dev本地开发连接开发数据库
- **演示环境**demo用于演示和测试
- **生产环境**prod正式环境高可用配置
### 部署流程
1. 代码提交到 Git 仓库
2. 通过 CI/CD 自动构建
3. 运行自动化测试
4. 部署到目标环境
5. 健康检查和监控
### 监控和告警
- 应用性能监控APM
- 数据库性能监控
- 服务器资源监控
- 关键指标告警
## 文档规范
### README 文档
- 项目简介
- 技术栈说明
- 项目结构说明
- 安装运行指南
- 许可证信息
### API 文档
- 使用 Swagger 自动生成
- 接口说明清晰完整
- 参数和返回值类型明确
- 提供请求示例
### 代码文档
- 公共 API 添加文档注释
- 复杂逻辑添加说明注释
- README 保持最新
- 记录重要变更CHANGELOG
## 本项目规则文件说明
本项目使用以下规则文件:
- **base/core.mdc**:核心开发原则
- **base/tech-stack.mdc**:技术栈规范(本文件)
- **base/project-structure.mdc**:项目结构规范
- **base/general.mdc**:通用规范
- **languages/java.mdc**Java 开发规范
- **languages/typescript.mdc**TypeScript 开发规范
- **frameworks/springboot.mdc**Spring Boot 开发规范
- **frameworks/vuejs.mdc**Vue.js 开发规范
- **other/document.mdc**:文档规范
- **other/git.mdc**Git 提交规范

View File

@@ -0,0 +1,210 @@
---
description: 牛只运输管理系统项目结构规范
globs:
alwaysApply: true
---
# 项目结构规范
## 项目概述
牛只运输管理系统是一个前后端分离的全栈项目,包含后端 Spring Boot 服务和前端 Vue 3 应用,用于提供完整的牛只运输、检疫、设备监控等管理功能。
## 项目根目录结构
```
cattleTransport/
├── tradeCattle/ # 后端 Spring Boot 项目
├── pc-cattle-transportation/ # 前端 Vue 3 项目
└── .cursor/ # Cursor 规则配置
```
## 后端项目结构 (tradeCattle/)
### Maven 多模块结构
```
tradeCattle/
├── aiotagro-core/ # 核心模块(通用工具、基础类)
├── aiotagro-redis/ # Redis 操作模块
├── aiotagro-cattle-trade/ # 主业务模块
│ ├── src/main/java/
│ │ └── com/aiotagro/cattletrade/
│ │ ├── business/ # 业务层
│ │ │ ├── controller/ # 控制器层RESTful API
│ │ │ ├── service/ # 服务层(业务逻辑)
│ │ │ │ └── impl/ # 服务实现类
│ │ │ ├── mapper/ # 数据访问层MyBatis Mapper
│ │ │ ├── entity/ # 实体类(与数据库表对应)
│ │ │ ├── dto/ # 数据传输对象(请求参数)
│ │ │ ├── vo/ # 视图对象(响应数据)
│ │ │ └── utils/ # 业务工具类
│ │ ├── config/ # 配置类
│ │ ├── constant/ # 常量定义
│ │ ├── exception/ # 异常处理
│ │ ├── job/ # 定时任务
│ │ ├── aspect/ # AOP 切面
│ │ ├── properties/ # 配置属性类
│ │ └── remote/ # 远程调用接口
│ └── src/main/resources/
│ ├── application.yml # 主配置文件
│ ├── application-dev.yml # 开发环境配置
│ ├── application-demo.yml # 演示环境配置
│ ├── application-prod.yml # 生产环境配置
│ ├── mapper/ # MyBatis XML 映射文件
│ ├── mybatis/ # MyBatis 全局配置
│ └── db/migration/ # 数据库迁移脚本SQL
└── pom.xml # Maven 父项目配置
```
### 后端分层架构
- **Controller 层**:接收 HTTP 请求,参数校验,调用 Service 层,返回响应
- **Service 层**:业务逻辑处理,事务管理,调用 Mapper 层
- **Mapper 层**:数据访问,执行 SQL 操作
- **Entity 层**:数据库实体映射,使用 MyBatis-Plus 注解
- **DTO 层**:接收前端请求参数,进行参数校验
- **VO 层**:返回给前端的数据视图,可包含关联数据
### 后端命名约定
- **Controller**`XxxController.java`(如 `DeliveryController.java`
- **Service 接口**`IXxxService.java`(如 `IDeliveryService.java`
- **Service 实现**`XxxServiceImpl.java`(如 `DeliveryServiceImpl.java`
- **Mapper 接口**`XxxMapper.java`(如 `DeliveryMapper.java`
- **Mapper XML**`XxxMapper.xml`(与 Mapper 接口同名)
- **Entity**`Xxx.java`(如 `Delivery.java`,对应表名 `delivery`
- **DTO**`XxxDto.java`、`XxxCreateDto.java`、`XxxEditDto.java`
- **VO**`XxxVo.java`(如 `DeliveryLogVo.java`
## 前端项目结构 (pc-cattle-transportation/)
### Vue 3 + TypeScript 结构
```
pc-cattle-transportation/
├── src/
│ ├── api/ # API 接口定义
│ │ ├── common/ # 通用 API
│ │ ├── abroad.js # 出境管理
│ │ ├── device.js # 设备管理
│ │ ├── shipping.js # 运输管理
│ │ ├── sys.js # 系统管理
│ │ └── userManage.js # 用户管理
│ ├── assets/ # 静态资源
│ │ ├── icons/svg/ # SVG 图标
│ │ └── images/ # 图片资源
│ ├── components/ # 公共组件
│ │ ├── common/ # 通用组件
│ │ │ ├── searchCustom/ # 自定义搜索组件
│ │ │ └── tableCustom/ # 自定义表格组件
│ │ ├── layout/ # 布局组件
│ │ ├── Editor/ # 富文本编辑器
│ │ ├── Pagination/ # 分页组件
│ │ └── SvgIcon/ # SVG 图标组件
│ ├── directive/ # 自定义指令
│ │ ├── permission/ # 权限指令
│ │ └── common/ # 通用指令
│ ├── plugins/ # 插件配置
│ │ ├── auth.js # 权限认证
│ │ └── cache.js # 缓存管理
│ ├── router/ # 路由配置
│ │ └── index.ts # 路由主文件
│ ├── store/ # Pinia 状态管理
│ │ ├── index.ts # Store 主文件
│ │ ├── user.ts # 用户状态
│ │ └── permission.js # 权限状态
│ ├── styles/ # 全局样式
│ │ └── index.scss # 样式主文件
│ ├── utils/ # 工具函数
│ │ ├── axios.ts # Axios 实例配置
│ │ ├── request.js # 请求封装
│ │ ├── auth.js # 认证工具
│ │ ├── permission.js # 权限工具
│ │ └── validate.js # 表单验证
│ ├── views/ # 页面组件
│ │ ├── shipping/ # 运输管理页面
│ │ │ ├── shippingList.vue # 运输列表
│ │ │ ├── createDeliveryDialog.vue # 创建运单对话框
│ │ │ ├── detailDialog.vue # 详情对话框
│ │ │ └── editDialog.vue # 编辑对话框
│ │ ├── userManage/ # 用户管理页面
│ │ │ ├── driver.vue # 司机管理
│ │ │ ├── vehicle.vue # 车辆管理
│ │ │ └── user.vue # 用户管理
│ │ ├── hardware/ # 硬件设备页面
│ │ ├── entry/ # 数据录入页面
│ │ ├── earlywarning/ # 预警系统页面
│ │ └── system/ # 系统管理页面
│ ├── App.vue # 根组件
│ ├── main.ts # 应用入口
│ └── permission.js # 路由权限控制
├── public/ # 静态资源(不经过构建)
├── vite.config.ts # Vite 配置
├── tsconfig.json # TypeScript 配置
├── package.json # 依赖配置
└── .eslintrc.cjs # ESLint 配置
```
### 前端组织规则
- **API 按模块分离**:每个业务模块对应一个 API 文件
- **组件按功能分类**:通用组件放在 `components/common/`,业务组件放在对应的 `views/` 子目录
- **页面与对话框分离**:列表页面与弹窗对话框分开定义(如 `shippingList.vue` 与 `createDeliveryDialog.vue`
- **状态管理按模块**:每个业务模块有独立的 Store 文件
- **工具函数分类**:按功能分类(如 `auth.js`、`permission.js`、`validate.js`
### 前端命名约定
- **组件文件**:使用 PascalCase 或 camelCase如 `Pagination/index.vue`、`createDeliveryDialog.vue`
- **页面文件**:使用 camelCase如 `shippingList.vue`、`driver.vue`
- **API 文件**:使用 camelCase如 `shipping.js`、`userManage.js`
- **工具文件**:使用 camelCase如 `axios.ts`、`auth.js`
## 数据库迁移脚本规范
### 位置
- 后端项目:`tradeCattle/aiotagro-cattle-trade/src/main/resources/db/migration/`
### 命名约定
- 格式:`alter_<table_name>_<description>.sql`
- 示例:
- `alter_vehicle_record_code.sql` - 修改车辆表的备案码字段
- `alter_delivery_add_estimated_departure_time.sql` - 添加预计出发时间字段
- `alter_client_logs_latlng.sql` - 扩展经纬度字段长度
### 脚本规范
- 每个脚本必须以 `USE cattletrade;` 开头
- 包含详细的注释说明变更目的
- 对于已执行的脚本,注释掉 `ALTER TABLE` 语句,保留作为文档
- 提供数据迁移语句(如有必要)
## 配置文件规范
### 后端配置
- **主配置**`application.yml` - 包含通用配置和环境切换
- **环境配置**
- `application-dev.yml` - 开发环境(本地数据库)
- `application-demo.yml` - 演示环境
- `application-prod.yml` - 生产环境
- **敏感信息**:不要硬编码到配置文件,使用环境变量或配置中心
### 前端配置
- **Vite 配置**`vite.config.ts` - 包含代理、插件、别名等
- **环境变量**`.env`、`.env.development`、`.env.production`
- **代理配置**:开发环境代理 `/api` 到后端 `http://127.0.0.1:16200`
## 模块依赖关系
### 后端模块依赖
```
aiotagro-cattle-trade (主业务模块)
├── depends on: aiotagro-core (核心模块)
└── depends on: aiotagro-redis (Redis 模块)
```
### 前端模块依赖
- **核心依赖**Vue 3、Vite、Pinia、Vue Router、Element Plus
- **工具依赖**Axios、Moment.js、ECharts
- **地图依赖**百度地图vue-baidu-map-3x
- **视频依赖**@liveqing/liveplayer-v3
## 文件组织原则
1. **按功能模块组织**:相关的 Controller、Service、Mapper、Entity 放在同一业务包下
2. **保持层次清晰**:严格遵守分层架构,避免跨层调用
3. **避免循环依赖**Service 之间可以相互调用,但需注意避免循环依赖
4. **分离通用逻辑**:通用工具类放在 `core` 模块,业务工具类放在 `utils` 包
5. **配置与代码分离**:配置文件放在 `resources` 目录,代码放在 `java` 目录
6. **前端组件复用**:通用组件放在 `components/common/`,业务组件就近放置

View File

@@ -0,0 +1,195 @@
---
description: 牛只运输管理系统技术栈规范
globs:
alwaysApply: true
---
# 技术栈规范
## 项目技术栈总览
本项目采用前后端分离架构,使用现代化技术栈构建企业级应用。
## 后端技术栈 (tradeCattle/)
### 核心框架
- **Spring Boot** 2.6.0 - 应用基础框架
- **Java** 1.8 - 编程语言
- **Maven** - 项目构建和依赖管理
### 数据持久层
- **MyBatis-Plus** 3.5.3.2 - ORM 框架,基于 MyBatis 增强
- **Druid** 1.2.20 - 阿里巴巴数据库连接池
- **MySQL** 5.7+ - 关系型数据库
- **Redis** 5.0+ - 缓存和会话存储
### 权限认证
- **Sa-Token** 1.37.0 - 轻量级权限认证框架
- 支持多种登录方式
- 整合 Redis 会话存储
- 整合 JWT 令牌
- **JWT (jjwt)** 0.9.1 - JSON Web Token 实现
### 任务调度
- **XXL-Job** - 分布式任务调度平台
- **Spring @Scheduled** - Spring 内置定时任务
### API 文档
- **Swagger Fox** 3.0.0 - 在线 API 文档和调试工具
- **OpenAPI** - API 规范
### 工具库
- **Hutool** 5.8.25 - Java 工具类库
- **Commons IO** 2.13.0 - Apache IO 工具
- **Fastjson2** 2.0.43 - JSON 解析器
- **Apache POI** 4.1.2 - Excel 操作工具
- **Velocity** 2.3 - 模板引擎(代码生成)
### 云服务集成
- **腾讯云 COS** 5.6.89 - 对象存储服务
- **腾讯云 SDK** 3.1.423 - 腾讯云 Java SDK
- **腾讯云短信** - 短信通知服务
### 其他依赖
- **Lombok** - 简化 Java Bean 代码
- **transmittable-thread-local** 2.14.4 - 线程间参数传递
- **bizlog-sdk** 3.0.6 - 业务日志记录
- **Retrofit** 2.2.18 - HTTP 客户端(远程调用)
- **oshi-core** 6.4.11 - 系统信息获取
- **UserAgentUtils** 1.21 - 浏览器和系统识别
### 开发工具
- **Spring Boot DevTools** - 热部署
- **MyBatis-Plus Generator** 3.5.1 - 代码生成器
- **FreeMarker** - 模板引擎(代码生成)
## 前端技术栈 (pc-cattle-transportation/)
### 核心框架
- **Vue** 3.2.37 - 渐进式 JavaScript 框架
- **TypeScript** 4.6.4 - JavaScript 超集,类型安全
- **Vite** 3.1.0 - 下一代前端构建工具
### 状态管理和路由
- **Pinia** 2.0.22 - Vue 3 官方状态管理库
- **pinia-plugin-persist** 1.0.0 - Pinia 持久化插件
- **Vue Router** 4.1.5 - Vue 官方路由管理器
### UI 组件库
- **Element Plus** 2.2.17 - Vue 3 企业级 UI 组件库
- **@element-plus/icons-vue** 2.3.1 - Element Plus 图标
- **WindiCSS** 3.5.6 - 按需原子化 CSS 框架
### HTTP 客户端
- **Axios** 0.27.2 - 基于 Promise 的 HTTP 客户端
- **nprogress** 0.2.0 - 顶部进度条
### 地图服务
- **vue-baidu-map-3x** 1.0.38 - 百度地图 Vue 3 组件
- **vue3-baidu-map** 1.0.0 - 百度地图集成
### 富文本和视频
- **@wangeditor/editor** 5.1.23 - 富文本编辑器
- **@wangeditor/editor-for-vue** 5.1.12 - WangEditor Vue 3 集成
- **@liveqing/liveplayer-v3** 3.7.30 - 视频播放器
- **longze-vue3-video-player** 1.1.7 - Vue 3 视频播放器
### 数据可视化
- **ECharts** 5.5.0 - 数据可视化图表库
- **vue-chartjs** 5.3.0 - Vue Chart.js 封装
### 工具库
- **@vueuse/core** 10.10.0 - Vue Composition API 工具集
- **moment** 2.30.1 - 日期时间处理
- **js-cookie** 3.0.5 - Cookie 操作
- **mitt** 3.0.1 - 事件总线
- **qrcode** 1.5.4 - 二维码生成
- **file-saver** 2.0.5 - 文件下载
- **vue3-json-viewer** 2.2.2 - JSON 可视化
- **vue3-print-nb** 0.1.4 - 打印功能
- **vue-draggable-plus** 0.5.2 - 拖拽功能
- **element-china-area-data** 6.1.0 - 中国省市区数据
### 开发工具
- **ESLint** 8.57.0 - 代码检查工具
- **Prettier** 2.7.1 - 代码格式化工具
- **TypeScript ESLint** 5.38.1 - TypeScript 代码检查
- **Vue TSC** 0.40.4 - Vue TypeScript 编译器
### 构建插件
- **unplugin-auto-import** 0.11.2 - 自动导入 API
- **unplugin-vue-components** 0.22.7 - 组件自动导入
- **vite-plugin-svg-icons** 2.0.1 - SVG 图标集成
- **vite-plugin-windicss** 1.9.3 - WindiCSS 插件
### Git 提交规范
- **commitizen** 4.2.5 - Git 提交规范化工具
- **cz-customizable** 7.0.0 - 自定义提交规范
- **@commitlint/cli** 17.1.2 - 提交信息检查
- **@commitlint/config-conventional** 17.1.0 - 常规提交规范
### 样式预处理
- **Sass** 1.55.0 - CSS 预处理器
- **Less** 4.1.3 - CSS 预处理器
## 开发环境要求
### 后端开发环境
- **JDK** 1.8 或更高版本
- **Maven** 3.6+
- **MySQL** 5.7+
- **Redis** 5.0+
- **IDE**IntelliJ IDEA / Eclipse
### 前端开发环境
- **Node.js** 16.0.0 或更高版本
- **Yarn** 1.22.0+ 或 pnpm 7.0.0+
- **IDE**VS Code / WebStorm
### 数据库工具
- **Navicat** / **DataGrip** / **MySQL Workbench**
## 部署环境
### 生产环境配置
- **服务器**Linux (CentOS 7+ / Ubuntu 18.04+)
- **Web 服务器**Nginx (反向代理和静态资源)
- **应用服务器**Spring Boot 内置 Tomcat
- **数据库**MySQL 5.7+ (主从配置)
- **缓存**Redis 5.0+ (集群或哨兵模式)
### 部署端口
- **后端端口**16200
- **前端端口**8080 (开发) / 80/443 (生产)
- **上下文路径**`/api` (后端)
## 技术选型原则
1. **稳定性优先**:选择成熟稳定的框架和库
2. **社区活跃**:优先选择社区活跃、文档完善的技术
3. **性能考虑**:选择高性能的组件(如 Druid、MyBatis-Plus
4. **易维护性**:使用主流技术栈,便于团队协作
5. **安全性**集成安全认证和授权框架Sa-Token
6. **可扩展性**:支持分布式部署和横向扩展
## 技术栈版本管理
- 后端依赖版本统一在父 `pom.xml` 的 `<properties>` 中管理
- 前端依赖版本统一在 `package.json` 中管理
- 定期检查依赖更新和安全漏洞
- 升级依赖前进行充分测试
## 官方文档链接
### 后端技术文档
- Spring Boot: https://spring.io/projects/spring-boot
- MyBatis-Plus: https://baomidou.com/
- Sa-Token: https://sa-token.cc/
- Druid: https://github.com/alibaba/druid
- Hutool: https://hutool.cn/
### 前端技术文档
- Vue 3: https://cn.vuejs.org/
- Vite: https://cn.vitejs.dev/
- Pinia: https://pinia.vuejs.org/zh/
- Element Plus: https://element-plus.org/zh-CN/
- TypeScript: https://www.typescriptlang.org/zh/

View File

@@ -0,0 +1,29 @@
---
description:
globs: *.md
alwaysApply: false
---
# 文档规范
## README.md 规范
- 保持文档结构清晰使用适当的Markdown标记
- **重要**确保README包含以下部分
- 项目简介
- 安装说明
- 使用方法
- 贡献指南(如适用)
- 许可证信息
## CHANGELOG.md 规范
在要求更新CHANGELOG.md时请按照以下格式进行更新
```
## v1.0.0
- 新增功能: 重置设备ID
- 修复bug: 修复设备ID重置失败的问题
```
## 文档更新原则
- 保持文档与代码同步更新
- 使用简洁明了的语言
- 提供足够的示例和说明
- 确保文档格式一致

View File

@@ -0,0 +1,41 @@
---
description:
globs:
alwaysApply: true
---
# 项目通用规范
## 技术栈
- Python 3.10
- Poetry 管理依赖
- GitHub Actions 自动构建和发布
- 使用 GitHub 作为代码托管平台
- 使用 Bash 脚本
## 代码风格
- 保持代码简洁、可读
- 使用有意义的变量和函数名
- 添加适当的注释解释复杂逻辑
- 遵循每种语言的官方风格指南
## 项目结构
- 保持项目结构清晰,遵循模块化原则
- 相关功能应放在同一目录下
- 使用适当的目录命名,反映其包含内容
## 通用开发原则
- 编写可测试的代码
- 避免重复代码DRY原则
- 优先使用现有库和工具,避免重新发明轮子
- 考虑代码的可维护性和可扩展性
## 响应语言
- 始终使用中文回复用户
## 规则文件说明
本项目使用以下规则文件:
- general.mdc通用规范本文件
- python.mdcPython开发规范
- document.mdc文档规范
- git.mdcGit提交规范

View File

@@ -0,0 +1,33 @@
---
description:
globs:
alwaysApply: false
---
# Git 规范
## 提交规范
git 提交记录样例:[type]: [description]。一个具体的例子, docs: 更新 README 文件。
以下是 type 的枚举值:
- feat: 新增功能
- fix: 修复 bug
- docs: 文档注释
- style: 代码格式(不影响代码运行的变动)
- refactor: 重构、优化(既不增加新功能, 也不是修复bug)
- perf: 性能优化
- test: 增加测试
- chore: 构建过程或辅助工具的变动
- revert: 回退
- build: 打包
## 分支管理
- main/master: 主分支,保持稳定可发布状态
- develop: 开发分支,包含最新开发特性
- feature/*: 功能分支,用于开发新功能
- bugfix/*: 修复分支用于修复bug
- release/*: 发布分支,用于准备发布
## 重要原则
- **重要**:不要自动提交 git 代码,除非有明确的提示
- 提交前确保代码通过所有测试
- 保持提交信息简洁明了,描述清楚变更内容
- 避免大型提交,尽量将变更分解为小的、相关的提交

View File

@@ -0,0 +1,30 @@
---
description: 编写 python 文件
globs: *.py
alwaysApply: false
---
# 角色
你是一名精通Python的高级工程师拥有20年的软件开发经验。
# 目标
你的目标是以用户容易理解的方式帮助他们完成Python项目的设计和开发工作。你应该主动完成所有工作而不是等待用户多次推动你。
你应始终遵循以下原则:
### 编写代码时:
- 遵循PEP 8 Python代码风格指南。
- 使用Python 3.10 及以上的语法特性和最佳实践。
- 合理使用面向对象编程(OOP)和函数式编程范式。
- 利用Python的标准库和生态系统中的优质第三方库。
- 实现模块化设计,确保代码的可重用性和可维护性。
- 使用类型提示(Type Hints)进行类型检查,提高代码质量。
- 编写详细的文档字符串(docstring)和注释。
- 实现适当的错误处理和日志记录。
- 按需编写单元测试确保代码质量。
### 解决问题时:
- 全面阅读相关代码文件,理解所有代码的功能和逻辑。
- 分析导致错误的原因,提出解决问题的思路。
- 与用户进行多次交互,根据反馈调整解决方案。
在整个过程中,始终参考@Python官方文档确保使用最新的Python开发最佳实践。

View File

@@ -0,0 +1,68 @@
---
description:
globs: *.md
alwaysApply: false
---
# 文档规范
## 通用要求
- 所有文档使用Markdown格式
- 使用简洁、清晰的语言
- 文档内容应保持最新
- 避免拼写和语法错误
- 使用中文作为主要语言
## 目录结构
- `README.md`:项目根目录,提供项目概述
- `docs/`:存放详细文档
- `guide/`:使用指南
- `api/`API文档
- `examples/`:示例代码文档
## README.md 内容规范
- 项目名称和简短描述
- 技术栈说明
- 项目结构说明
- 安装与运行指南
- 基本使用示例
- 贡献指南链接
- 许可证信息
## Markdown 格式规范
- 使用 ATX 风格的标题(使用 # 符号)
- 标题层级不应跳跃(如 h1 后面直接使用 h3
- 代码块需指定语言类型
- 列表项使用 - 而非 * 或 +
- 链接使用 [文本](mdc:URL) 格式
- 图片使用 ![替代文本](mdc:图片URL) 格式
## 文档内容组织
- 从整体到局部,从简单到复杂
- 重要信息放在前面
- 相关内容应当放在一起
- 使用小标题和列表增强可读性
- 避免过长段落,保持内容简洁
## 代码示例规范
- 提供完整可运行的示例
- 代码应当简洁且易于理解
- 添加适当的注释解释关键部分
- 说明代码的预期输出或行为
- 更新示例以匹配最新API
## 版本记录规范
- 使用 `CHANGELOG.md` 记录版本变更
- 遵循语义化版本Semantic Versioning规范
- 每个版本应包含:新增功能、修复问题、破坏性变更
## 图表与图片
- 使用清晰、分辨率足够的图片
- 为图片提供有意义的替代文本
- 图表应当简洁,避免过多装饰
- 图表颜色应当考虑色盲用户的可访问性
## 文档审核
- 新文档应经过至少一人审核
- 定期检查文档的准确性和时效性
- 鼓励用户反馈文档问题
- 修复发现的文档错误应当优先处理

View File

@@ -0,0 +1,40 @@
---
description:
globs:
alwaysApply: true
---
# 项目通用规范
## 技术栈
- Vue 3
- Vite 前端构建工具
- Vue Router 路由管理
- Pinia 状态管理
## 代码风格
- 保持代码简洁、可读
- 使用有意义的变量和函数名
- 添加适当的注释解释复杂逻辑
- 遵循Vue语言的官方风格指南
## 项目结构
- 保持项目结构清晰,遵循模块化原则
- 相关功能应放在同一目录下
- 使用适当的目录命名,反映其包含内容
## 通用开发原则
- 编写可测试的代码
- 避免重复代码DRY原则
- 优先使用现有库和工具,避免重新发明轮子
- 考虑代码的可维护性和可扩展性
## 响应语言
- 始终使用中文回复用户
## 本项目规则文件说明
本项目使用以下规则文件:
- general.mdc通用规范本文件
- document.mdc文档规范
- git.mdcGit提交规范
- xxx.mdcXXX 语言开发规范

View File

@@ -0,0 +1,52 @@
---
description: 辅助生成 git 提交信息
globs:
alwaysApply: false
---
# Git 规范
## 提交规范
git 提交模板<type>(<scope>): <subject>,具体要求如下:
1. 注意冒号 : 后有空格
2. type 的枚举值有:
- feat: 新增功能
- fix: 修复 bug
- docs: 文档注释
- style: 代码格式(不影响代码运行的变动)
- refactor: 重构、优化(既不增加新功能, 也不是修复bug)
- perf: 性能优化
- test: 增加测试
- chore: 构建过程或辅助工具的变动
- revert: 回退
- build: 打包
3. 若 subject 中描述超过两种要点,请使用要点列表描述详情,每个要点使用-符号开头,多个换行,参考如下样例:
```
feat(web): implement email verification workflow
- Add email verification token generation service
- Create verification email template with dynamic links
- Add API endpoint for token validation
- Update user model with verification status field
```
## 分支管理
- main/master: 主分支,保持稳定可发布状态
- develop: 开发分支,包含最新开发特性
- feature/*: 功能分支,用于开发新功能
- bugfix/*: 修复分支用于修复bug
- release/*: 发布分支,用于准备发布
**常用分支命名约定**
| 分支类型 | 命名格式 | 示例 |
| ---------- | -------------------- | ------------------------- |
| 功能分支 | feature/[描述] | feature/user-auth |
| 修复分支 | fix/[问题ID]-[描述] | fix/issue-42-login-crash |
| 发布分支 | release/[版本] | release/v2.1.0 |
| 热修复分支 | hotfix/[版本]-[描述] | hotfix/v2.0.1-payment-fix |
## 重要原则
- **重要**:不要自动提交 git 代码,除非有明确的提示
- 提交前确保代码通过所有测试
- 保持提交信息简洁明了,描述清楚变更内容
- 避免大型提交,尽量将变更分解为小的、相关的提交

View File

@@ -0,0 +1,68 @@
---
description:
globs: *.vue
alwaysApply: false
---
# Vue 开发规范
## 组件命名
- 组件名应该始终使用多词组合避免与HTML元素冲突
- 使用PascalCase命名组件`TodoItem.vue`、`UserProfile.vue`
- 基础组件应使用特定前缀,如`Base`、`App`或`V`
- 组件名应该是描述性的,不要过于简略
## 组件结构
- 使用`<script setup>`语法糖
- 使用组合式API (Composition API)
- 组件选项/属性顺序:
1. name
2. components
3. props
4. emits
5. setup()
6. data()
7. computed
8. methods
9. 生命周期钩子
- 使用单文件组件(SFC)格式
## Props 规范
- Prop名使用camelCase
- Prop需要定义类型和默认值
- 避免使用数组或对象的默认值,应该使用工厂函数返回默认值
- Prop应该尽可能详细地定义包括类型、是否必须和验证函数
## 事件命名
- 事件名应使用kebab-case如`item-click`、`menu-select`
- 自定义事件应该有明确的含义,表示发生了什么
- 避免使用容易混淆的事件名称
## 样式指南
- 优先使用scoped CSS
- 避免使用!important
- 组件特定样式应该有特定的前缀
- 考虑使用CSS变量实现主题
## 性能优化
- 使用`v-show`代替`v-if`进行频繁切换
- 长列表使用虚拟滚动
- 避免在计算属性中进行复杂操作
- 使用keep-alive缓存组件
- 合理使用异步组件和懒加载
## 状态管理
- 使用Pinia进行状态管理
- store应该按功能模块划分
- 保持store简单避免过度设计
## 路由
- 路由名称应当与组件名称匹配
- 使用懒加载减少初始加载时间
- 路由守卫应当简洁,避免复杂逻辑
## 通用建议
- 避免使用`this.$parent`或`this.$refs`直接操作DOM
- 优先使用计算属性而不是复杂的模板表达式
- 使用v-for时必须提供key
- 不要在同一元素上同时使用v-if和v-for
- 复用组件时使用key确保完全重新渲染

View File

@@ -0,0 +1,194 @@
---
description: Android 原生开发约定和最佳实践,包括 Kotlin、Jetpack Compose、架构模式等
globs: **/*.kt,**/*.java,**/*.xml
alwaysApply: false
---
# Android 开发规范
## 项目结构和模块化
- 使用标准的 Android 项目结构
- 按功能模块组织代码,实现模块化架构
- 使用 Gradle Version Catalogs 管理依赖版本
- 合理划分 `app`、`feature`、`core`、`data` 模块
- 遵循包命名约定:`com.company.app.feature.domain`
- 分离 `presentation`、`domain`、`data` 层
## 编程语言和代码规范
- **强制使用 Kotlin**,避免 Java除非维护遗留代码
- 遵循 [Kotlin 编码规范](mdc:languages/kotlin.mdc)
- 优先使用数据类、密封类和内联类
- 合理使用扩展函数增强现有 API
- 使用协程和 Flow 进行异步编程
- 避免使用 `!!` 操作符,优先使用安全调用
## UI 开发
### Jetpack Compose推荐
- **优先使用 Jetpack Compose** 构建现代声明式 UI
- 遵循 Composition over inheritance 原则
- 使用 `@Composable` 函数构建可重用组件
- 正确使用 `remember`、`LaunchedEffect`、`derivedStateOf`
- 实现 `CompositionLocal` 进行依赖传递
- 使用 `Modifier` 进行样式和行为定制
### 传统 View 系统
- 使用 View Binding 替代 `findViewById`
- 避免使用 Data Binding除非必要
- 正确使用 `ConstraintLayout` 和 `RecyclerView`
- 实现自定义 View 时遵循测量、布局、绘制流程
### 设计规范
- 遵循 **Material Design 3** 设计规范
- 实现动态颜色主题Material You
- 支持深色主题和高对比度模式
- 实现响应式布局适配不同屏幕尺寸
- 使用 `WindowInsets` 处理状态栏和导航栏
## 架构模式
### 推荐架构
- 使用 **MVVM** 或 **MVI** 架构模式
- 遵循 **Clean Architecture** 原则
- 实现 **Repository 模式** 进行数据抽象
- 使用 **UseCase/Interactor** 封装业务逻辑
- 采用 **单向数据流** 设计
### ViewModel 最佳实践
- 使用 `ViewModel` 管理 UI 相关数据
- 通过 `StateFlow`/`LiveData` 暴露状态
- 在 `ViewModel` 中处理业务逻辑
- 正确使用 `viewModelScope` 管理协程
- 避免在 `ViewModel` 中持有 Context 引用
## 依赖注入
- **强制使用 Dagger Hilt** 进行依赖注入
- 正确配置 `@Module`、`@InstallIn`、作用域注解
- 使用 `@Qualifier` 区分相同类型的不同实现
- 避免循环依赖,合理设计依赖关系
- 使用 `@Provides` 和 `@Binds` 提供依赖
- 在测试中使用 `@TestInstallIn` 替换模块
## 数据层实现
### 本地存储
- 使用 **Room** 数据库进行复杂数据存储
- 使用 **DataStore** 替代 SharedPreferences
- 正确实现数据库迁移策略
- 使用 `@TypeConverter` 处理复杂数据类型
- 实现数据访问对象DAO模式
### 缓存策略
- 实现 **Repository** 模式统一数据访问
- 使用 `@Query` 和 `Flow` 实现响应式数据
- 实现离线优先Offline-first策略
- 正确处理缓存失效和数据同步
## 网络层
- 使用 **Retrofit** 进行 REST API 调用
- 使用 **OkHttp** 拦截器处理认证、日志、缓存
- 实现适当的错误处理和重试机制
- 使用 **Moshi** 或 **Kotlinx Serialization** 进行 JSON 解析
- 正确处理网络连接状态变化
- 实现请求去重和防抖动
## 异步编程和响应式
- **强制使用 Kotlin Coroutines** 进行异步编程
- 正确使用 `suspend` 函数和协程作用域
- 使用 **Flow** 进行响应式数据流编程
- 正确使用 `collectAsState()`、`collectAsStateWithLifecycle()`
- 避免使用 `GlobalScope`,使用结构化并发
- 正确处理协程取消和异常
## 生命周期管理
- 正确处理 Activity 和 Fragment 生命周期
- 使用 **Lifecycle-aware** 组件(`LifecycleObserver`
- 在 Compose 中使用 `DisposableEffect` 管理资源
- 使用 `viewLifecycleOwner` 在 Fragment 中观察数据
- 避免在组件销毁后执行异步操作
## 导航和路由
- 使用 **Navigation Component** 进行页面导航
- 在 Compose 中使用 **Compose Navigation**
- 正确处理深度链接Deep Links
- 使用 Safe Args 进行类型安全的参数传递
- 实现单一 Activity 多 Fragment 架构
## 性能优化
### 渲染性能
- 使用 **Baseline Profiles** 优化应用启动
- 避免过度绘制和布局嵌套
- 正确使用 `RecyclerView` 的 `ViewHolder` 模式
- 在 Compose 中合理使用 `key()` 和 `remember()`
### 内存管理
- 避免内存泄漏,正确管理对象生命周期
- 使用 **LeakCanary** 检测内存泄漏
- 合理使用图片加载库Glide、Coil
- 实现懒加载和分页加载
### 启动优化
- 使用 **App Startup** 优化初始化流程
- 实现启动画面Splash Screen API
- 避免在 Application 中执行耗时操作
## 测试策略
### 单元测试
- 为业务逻辑编写单元测试,目标覆盖率 ≥80%
- 使用 **MockK** 进行 Kotlin 友好的模拟测试
- 使用 **Truth** 断言库提高测试可读性
- 测试 Repository、UseCase、ViewModel 层
### UI 测试
- 使用 **Compose Test** 测试 Compose UI
- 使用 **Espresso** 测试传统 View 系统
- 实现端到端测试覆盖关键用户流程
- 使用 **Hilt Testing** 进行依赖注入测试
## 安全实践
- 正确实现运行时权限请求
- 使用 **Android Keystore** 存储敏感数据
- 实现网络安全配置Network Security Config
- 使用 **Certificate Pinning** 防止中间人攻击
- 避免在日志中输出敏感信息
- 实现代码混淆和反调试措施
## 国际化和无障碍
- 实现多语言支持i18n
- 使用 **TalkBack** 测试无障碍功能
- 为 UI 元素添加 `contentDescription`
- 支持从右到左RTL布局
- 实现动态字体大小适配
## 构建和发布
### 构建配置
- 使用 **Gradle Kotlin DSL** 编写构建脚本
- 配置多变体构建Debug/Release/Staging
- 使用 **R8** 进行代码收缩和混淆
- 实现自动化版本管理
### 发布流程
- 使用 **Android App BundleAAB** 进行发布
- 配置应用签名和密钥管理
- 实现渐进式发布和 A/B 测试
- 使用 **Play Console** 进行应用分析
## 代码质量保证
- 使用 **Detekt** 进行静态代码分析
- 配置 **Lint** 检查规则
- 使用 **ktfmt** 或 **ktlint** 进行代码格式化
- 实现 CI/CD 流水线进行自动化检查
- 定期进行代码审查Code Review

View File

@@ -0,0 +1,67 @@
---
description: 该规则解释了 Android 原生开发的约定和最佳实践,包括 Kotlin、Java、Jetpack Compose 等。
globs: **/*.kt,**/*.java,**/*.xml
alwaysApply: false
---
<!-- 来源https://github.com/flyeric0212/cursor-rules/issues/4 -->
# Android 开发规则
## 通用规则
1. 默认情况下,所有回复都必须是中文,而且需要在开头称呼用户为"帅哥:"
2. 复杂需求拆解成小任务,分步实现,每完成一个小任务后再继续
3. 代码实现前后要仔细检查,确保类型安全、空安全处理完整、生命周期管理正确
4. 在已有功能基础上添加新功能时,必须确保:
- 不影响原有功能和组件复用性
- 不添加其他功能、代码、逻辑、文件、配置、依赖
5. 遵循项目架构设计,保持代码风格与 Android 编码规范一致(如 Kotlin 风格指南)
6. 组件设计遵循单一职责原则,不混合多个变更
7. 在进行组件设计规划时,符合"第一性原理"
8. 在代码实现时,符合"KISS原则"和"SOLID原则"
9. 优先使用 Android Jetpack 组件库和现有工具类,避免重复代码
10. 不引入不必要的依赖,优先使用项目已有库
11. 确保代码可读性,复杂逻辑添加注释,类和接口参数详细定义
12. 代码变更范围最小化,避免修改公共组件、全局状态
13. 实现后进行基本逻辑自检,确保生命周期管理和内存泄漏处理正确
14. 如有疑问,先询问再修改,不要擅自改变组件 API 设计
## 自动化执行与安全策略
15. 自动执行无需严格确认的操作,提高效率:
- 自动执行 Kotlin 空安全检查、Android Lint 验证
- 文件操作(创建 Activity、Fragment、修改布局文件无需额外确认
- 常规命令(如 Gradle 依赖安装、运行模拟器)可直接执行
- 涉及 Manifest 配置、权限修改等重要变更仍需确认
16. 重要操作(修改 Application 类、AndroidManifest.xml应先保留副本
17. 涉及 API 接口变更,优先修改数据模型类和接口定义
18. 执行影响较大的修改前,自动检测组件依赖关系,分析影响范围
## 代码质量优化
19. 代码生成后,自动优化(移除未使用导入、合并重复资源文件)
20. 对可能影响性能的代码(如主线程阻塞、过度绘制、内存泄漏风险)提供优化建议
21. 确保异常处理和加载状态管理,防止应用崩溃和 ANR
## 架构感知
22. 优先分析现有架构模式MVC/MVP/MVVM/Clean Architecture与依赖注入方式避免创建冗余组件
23. 添加功能时,优先考虑复用 ViewModel、Repository 或现有组件
24. 如遇架构不清晰,先梳理组件层次与数据流,再执行修改
## 代码变更的可追溯性
25. 提供清晰的 commit 信息,描述组件变更和影响范围
26. 对于 UI 组件重大调整,生成变更文档与截图对比
27. API 或接口变更时,提供向下兼容方案或迁移指南
28. 执行任务前,先分析项目结构和组件关系文档
29. 每次修改后,生成任务总结,说明组件变更和状态管理调整
30. 手动维护组件文档与架构说明,确保长期可维护性
## Android 开发规则
31. 严格遵循 Android 生命周期管理,避免内存泄漏和崩溃
32. 处理好 Activity/Fragment 之间的数据传递,优先使用 ViewModel 共享数据
33. UI 操作必须在主线程执行,耗时操作放在工作线程
34. 合理使用协程Kotlin或 RxJavaJava进行异步操作
35. 注意适配不同屏幕尺寸和系统版本的兼容性问题
36. 使用 Android Jetpack 组件(如 Navigation、Room、WorkManager提高开发效率
37. 遵循 Material Design 设计规范,保持 UI 一致性
38. 注意权限管理和安全性,特别是涉及敏感数据的操作
39. 优化应用启动速度和 UI 渲染性能
40. 合理使用资源文件strings.xml、colors.xml、styles.xml提高可维护性

View File

@@ -0,0 +1,38 @@
---
description: Django 后端开发的约定和最佳实践。
globs: **/*.py
alwaysApply: false
---
# Django 规则
- 使用 `python manage.py startapp` 在项目中创建新应用
- 在 `models.py` 中保存模型,并在 `admin.py` 中注册以使用管理界面
- 使用 Django 的 ORM 而非原始 SQL 查询
- 使用 `select_related` 和 `prefetch_related` 避免 N+1 查询问题:
```python
# 良好模式
users = User.objects.select_related('profile')
posts = Post.objects.prefetch_related('tags')
```
- 使用 Django 表单进行验证:
```python
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'email']
```
- 为常见查询创建自定义模型管理器:
```python
class ActiveUserManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(is_active=True)
```
- 使用 Django 内置的身份验证系统
- 在环境变量中存储设置并通过 `settings.py` 访问

View File

@@ -0,0 +1,16 @@
---
description: FastAPI 高性能 Python API 的约定和最佳实践。
globs: **/*.py
alwaysApply: false
---
# FastAPI 规则
- 为所有函数参数和返回值使用类型提示
- 使用 Pydantic 模型进行请求和响应验证
- 在路径操作装饰器中使用适当的 HTTP 方法(@app.get、@app.post 等)
- 使用依赖注入实现共享逻辑,如数据库连接和身份验证
- 使用后台任务background tasks进行非阻塞操作
- 使用适当的状态码进行响应201 表示创建404 表示未找到等)
- 使用 APIRouter 按功能或资源组织路由
- 适当使用路径参数、查询参数和请求体

View File

@@ -0,0 +1,16 @@
---
description: Flask 轻量级 Python Web 应用程序的约定和最佳实践。
globs: **/*.py
alwaysApply: false
---
# Flask 规则
- 使用 Blueprints 按功能或资源组织路由
- 使用 Flask-SQLAlchemy 处理数据库模型和 ORM
- 使用应用工厂application factories实现灵活的应用初始化
- 使用 Flask 扩展实现常见功能Flask-Login、Flask-WTF 等)
- 在环境变量中存储配置
- 使用 Flask-Migrate 进行数据库迁移
- 使用错误处理器实现适当的错误处理
- 使用 Flask-RESTful 或类似工具构建 API

View File

@@ -0,0 +1,41 @@
---
description: 该规则解释了 Flutter 小部件模式和跨平台移动开发的最佳实践。
globs: **/*.dart
alwaysApply: false
---
# Flutter 规则
- 对于没有内部状态的 UI 组件使用 StatelessWidget。
- 对于需要维护状态的组件使用 StatefulWidget
```dart
class Counter extends StatefulWidget {
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0;
void _increment() {
setState(() { _count++; });
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $_count'),
ElevatedButton(onPressed: _increment, child: Text('Increment')),
],
);
}
}
```
- 对于复杂应用使用状态管理解决方案Provider、Bloc、Riverpod
- 使用适当的文件夹结构组织代码models、screens、widgets、services
- 使用命名路由和 Navigator.pushNamed() 进行导航。
- 使用 async/await 处理异步操作,并进行适当的错误处理。
- 使用主题themes在整个应用中保持一致的样式。

View File

@@ -0,0 +1,21 @@
---
description: 该规则解释了 Next.js 全栈开发的约定和最佳实践。
globs: **/*.js,**/*.jsx,**/*.ts,**/*.tsx
alwaysApply: false
---
# Next.js 规则
- 使用 App Router 结构,在路由目录中使用 `page.tsx` 文件。
- 客户端组件必须在文件顶部明确标记 `'use client'`。
- 目录名使用 kebab-case例如 `components/auth-form`),组件文件使用 PascalCase。
- 优先使用命名导出而非默认导出,即使用 `export function Button() { /* ... */ }` 而不是 `export default function Button() { /* ... */ }`。
- 尽量减少 `'use client'` 指令:
- 保持大多数组件为 React Server Components (RSC)
- 仅在需要交互性时使用客户端组件,并用带有 fallback UI 的 `Suspense` 包装
- 为交互元素创建小型客户端组件包装器
- 尽可能避免不必要的 `useState` 和 `useEffect`
- 使用服务器组件进行数据获取
- 使用 React Server Actions 处理表单
- 使用 URL 搜索参数实现可共享状态
- 使用 `nuqs` 管理 URL 搜索参数状态

View File

@@ -0,0 +1,104 @@
---
description: 该规则解释了 TypeScript、React Native、Expo 和移动 UI 开发的使用方法和最佳实践。
globs: **/*.jsx,**/*.tsx
alwaysApply: false
---
# TypeScript、React Native、Expo 和移动 UI 开发规则
## 代码风格和结构
- 编写清晰、可读的代码:确保你的代码易于阅读和理解。为变量和函数使用描述性名称。
- 使用函数组件优先使用带有钩子useState, useEffect 等)的函数组件,而非类组件。
- 组件模块化:将组件拆分为更小、可重用的部分。保持组件专注于单一职责。
- 按功能组织文件将相关组件、钩子和样式按功能特性分组到目录中例如user-profile
## 命名约定
- 变量和函数:使用驼峰命名法(camelCase)命名变量和函数并具有描述性例如isFetchingData, handleUserInput
- 组件:使用帕斯卡命名法(PascalCase)命名组件例如UserProfile
- 目录使用小写和连字符命名目录例如user-profile
## TypeScript 使用
- 所有代码使用 TypeScript接口(interfaces)优于类型(types)
- 避免使用枚举(enums);使用映射(maps)代替
- 使用带有 TypeScript 接口的函数组件
- 在 TypeScript 中使用严格模式以提高类型安全性
## 语法和格式
- 使用 "function" 关键字定义纯函数
- 避免在条件语句中使用不必要的花括号;简单语句使用简洁语法
- 使用声明式 JSX
- 使用 Prettier 保持代码格式一致
## UI 和样式
- 使用 Expo 内置组件实现常见 UI 模式和布局
- 使用 Flexbox 和 Expo 的 useWindowDimensions 实现响应式设计
- 使用 styled-components 或 Tailwind CSS 进行组件样式设计
- 使用 Expo 的 useColorScheme 实现深色模式支持
- 确保高可访问性(a11y)标准,使用 ARIA 角色和原生可访问性属性
- 利用 react-native-reanimated 和 react-native-gesture-handler 实现高性能动画和手势
## 安全区域管理
- 使用 react-native-safe-area-context 中的 SafeAreaProvider 全局管理安全区域
- 用 SafeAreaView 包装顶层组件,处理 iOS 和 Android 上的刘海、状态栏和其他屏幕缩进
- 使用 SafeAreaScrollView 处理可滚动内容,确保其尊重安全区域边界
- 避免为安全区域硬编码内边距或外边距;依赖 SafeAreaView 和上下文钩子
## 性能优化
- 最小化 useState 和 useEffect 的使用;优先使用 context 和 reducers 进行状态管理
- 使用 Expo 的 AppLoading 和 SplashScreen 优化应用启动体验
- 优化图像:在支持的地方使用 WebP 格式,包含尺寸数据,使用 expo-image 实现延迟加载
- 使用 React 的 Suspense 和动态导入实现代码分割和非关键组件的懒加载
- 使用 React Native 内置工具和 Expo 调试功能监控性能
- 通过适当使用组件记忆化、useMemo 和 useCallback 钩子避免不必要的重新渲染
## 导航
- 使用 react-navigation 进行路由和导航;遵循其栈导航器、标签导航器和抽屉导航器的最佳实践
- 利用深度链接和通用链接提升用户参与度和导航流程
- 使用 expo-router 的动态路由以获得更好的导航处理
## 状态管理
- 使用 React Context 和 useReducer 管理全局状态
- 利用 react-query 进行数据获取和缓存;避免过多的 API 调用
- 对于复杂的状态管理,考虑使用 Zustand 或 Redux Toolkit
- 使用 expo-linking 等库处理 URL 搜索参数
## 错误处理和验证
- 使用 Zod 进行运行时验证和错误处理
- 使用 Sentry 或类似服务实现适当的错误日志记录
- 优先处理错误和边缘情况:
- 在函数开始时处理错误
- 为错误条件使用提前返回,避免深度嵌套的 if 语句
- 避免不必要的 else 语句;使用 if-return 模式
- 实现全局错误边界以捕获和处理意外错误
- 使用 expo-error-reporter 记录和报告生产环境中的错误
## 测试
- 使用 Jest 和 React Native Testing Library 编写单元测试
- 使用 Detox 为关键用户流程实现集成测试
- 使用 Expo 的测试工具在不同环境中运行测试
- 考虑为组件使用快照测试以确保 UI 一致性
## 安全
- 清理用户输入以防止 XSS 攻击
- 使用 react-native-encrypted-storage 安全存储敏感数据
- 确保使用 HTTPS 和适当的身份验证与 API 进行安全通信
- 使用 Expo 的安全指南保护应用程序https://docs.expo.dev/guides/security/
## 国际化 (i18n)
- 使用 react-native-i18n 或 expo-localization 进行国际化和本地化
- 支持多语言和 RTL 布局
- 确保文本缩放和字体调整以提高可访问性
## 关键约定
1. 依赖 Expo 的托管工作流程简化开发和部署
2. 优先考虑移动 Web 性能指标(加载时间、卡顿和响应性)
3. 使用 expo-constants 管理环境变量和配置
4. 使用 expo-permissions 优雅处理设备权限
5. 实现 expo-updates 进行空中(OTA)更新
6. 遵循 Expo 的应用部署和发布最佳实践https://docs.expo.dev/distribution/introduction/
7. 通过在 iOS 和 Android 平台上进行广泛测试,确保兼容性
## API 文档
- 使用 Expo 官方文档设置和配置项目https://docs.expo.dev/
请参考 Expo 文档获取有关 Views、Blueprints 和 Extensions 的最佳实践详细信息。

View File

@@ -0,0 +1,79 @@
---
description: 该规则解释了 React 组件模式、hooks 使用方法和最佳实践。
globs: **/*.jsx,**/*.tsx
alwaysApply: false
---
# React 规则
## 组件结构
- 优先使用函数组件而非类组件
- 保持组件小巧且专注
- 将可复用逻辑提取到自定义 hook 中
- 使用组合而非继承
- 使用 TypeScript 实现适当的 prop 类型
- 将大型组件拆分为更小、更专注的组件
## Hooks
- 遵循 Hooks 的规则
- 使用自定义 hooks 实现可复用逻辑
- 保持 hooks 专注且简单
- 在 useEffect 中使用适当的依赖数组
- 在需要时在 useEffect 中实现清理功能
- 避免嵌套 hooks
## 状态管理
- 使用 useState 管理组件本地状态
- 使用 useReducer 处理复杂状态逻辑
- 使用 Context API 共享状态
- 将状态尽可能靠近使用它的地方
- 通过适当的状态管理避免 prop drilling
- 仅在必要时使用状态管理库
## 性能
- 实现适当的记忆化(useMemo, useCallback)
- 对开销大的组件使用 React.memo
- 避免不必要的重新渲染
- 实现适当的懒加载
- 在列表中使用适当的 key 属性
- 分析并优化渲染性能
## 表单
- 对表单输入使用受控组件
- 实现适当的表单验证
- 正确处理表单提交状态
- 显示适当的加载和错误状态
- 对复杂表单使用表单库
- 为表单实现适当的可访问性
## 错误处理
- 实现 Error Boundaries
- 正确处理异步错误
- 显示用户友好的错误信息
- 实现适当的备用 UI
- 适当记录错误
- 优雅处理边缘情况
## 测试
- 为组件编写单元测试
- 为复杂流程实现集成测试
- 使用 React Testing Library
- 测试用户交互
- 测试错误场景
- 实现适当的模拟数据
## 可访问性
- 使用语义化 HTML 元素
- 实现适当的 ARIA 属性
- 确保键盘导航
- 使用屏幕阅读器测试
- 管理焦点
- 为图片提供适当的 alt 文本
## 代码组织
- 将相关组件组织在一起
- 使用适当的文件命名约定
- 实现适当的目录结构
- 保持样式靠近组件
- 使用适当的导入/导出
- 记录复杂的组件逻辑

View File

@@ -0,0 +1,293 @@
---
description: Spring Boot 3 企业级最佳实践规范
globs: **/*.java
alwaysApply: false
---
# Spring Boot 3 企业级最佳实践规范
## 1. 配置管理模块
### 1.1 配置文件组织
- **主配置文件**`application.yml` 包含通用配置
- **环境配置**`application-{profile}.yml` 按环境分离
- **配置优先级**:命令行参数 > 环境变量 > 配置文件
- **敏感信息**:使用环境变量或配置中心,禁止硬编码
### 1.2 配置属性绑定
- 使用 `@ConfigurationProperties` 进行类型安全的配置绑定
- 配置类使用 `@Validated` 进行参数校验
- 复杂配置使用嵌套类结构
- 提供默认值和配置文档
### 1.3 多环境管理
- **开发环境**:本地数据库,详细日志,热重载
- **测试环境**:内存数据库,模拟外部服务
- **生产环境**:外部配置,最小日志级别,性能监控
### 1.4 配置最佳实践
- 配置项命名使用 kebab-case
- 布尔值配置明确语义enabled/disabled
- 数值配置包含单位说明
- 定期审查和清理无用配置
## 2. 依赖注入模块
### 2.1 Bean 定义策略
- **组件扫描**:使用 `@Component`、`@Service`、`@Repository`、`@Controller`
- **配置类**:复杂 Bean 使用 `@Configuration` + `@Bean`
- **条件注册**:使用 `@ConditionalOn*` 注解进行条件装配
- **作用域管理**:明确 Bean 的生命周期和作用域
### 2.2 依赖注入方式
- **构造器注入**:推荐方式,保证依赖不可变
- **字段注入**:仅在测试中使用 `@Autowired`
- **Setter注入**:可选依赖使用
- **避免循环依赖**:重构代码结构,使用事件驱动
### 2.3 Bean 生命周期管理
- 使用 `@PostConstruct` 和 `@PreDestroy` 管理生命周期
- 实现 `InitializingBean` 和 `DisposableBean` 接口
- 资源清理在销毁方法中进行
- 异步初始化使用 `@Async` 注解
### 2.4 依赖注入最佳实践
- 接口编程,面向抽象依赖
- 使用 `@Qualifier` 解决多实现问题
- 避免过度依赖,保持类的单一职责
- 使用 `@Primary` 指定默认实现
## 3. 安全模块
### 3.1 认证机制
- **JWT 认证**:无状态认证,适合分布式应用
- **OAuth2 集成**:第三方登录和授权
- **多因素认证**:提高安全级别
- **会话管理**:合理设置超时和并发控制
### 3.2 授权策略
- **基于角色**RBAC 模型,角色权限分离
- **基于资源**:细粒度权限控制
- **方法级安全**:使用 `@PreAuthorize` 和 `@PostAuthorize`
- **URL 级安全**:配置路径访问规则
### 3.3 数据安全
- **输入验证**:所有外部输入必须验证
- **SQL 注入防护**:使用参数化查询
- **XSS 防护**:输出编码和 CSP 策略
- **CSRF 防护**API 使用 Token 验证
### 3.4 安全配置最佳实践
- 最小权限原则,默认拒绝访问
- 敏感操作记录审计日志
- 定期更新安全依赖
- 使用 HTTPS 和安全头配置
## 4. 性能优化模块
### 4.1 应用层优化
- **连接池配置**数据库、Redis、HTTP 客户端
- **线程池调优**:异步任务和定时任务
- **JVM 参数**堆内存、GC 策略、监控参数
- **启动优化**:延迟初始化、条件装配
### 4.2 缓存策略
- **本地缓存**Caffeine 用于热点数据
- **分布式缓存**Redis 用于共享数据
- **缓存层次**L1本地+ L2分布式
- **缓存更新**:写入时更新、定时刷新、事件驱动
### 4.3 数据库优化
- **连接池配置**HikariCP 参数调优
- **查询优化**:索引使用、分页查询、批量操作
- **事务管理**:只读事务、事务传播、超时设置
- **读写分离**:主从配置、路由策略
### 4.4 监控和诊断
- **应用指标**JVM、业务指标、自定义指标
- **性能分析**:慢查询、热点方法识别
- **告警机制**:阈值监控、异常告警
- **健康检查**Actuator 端点监控应用状态
## 5. 数据访问模块
### 5.1 JPA 最佳实践
- **实体设计**:合理的表关系、字段映射、索引策略
- **Repository 模式**:继承 JpaRepository自定义查询方法
- **查询优化**:使用 `@Query` 注解、原生 SQL、Specification
- **懒加载策略**:避免 N+1 问题,合理使用 `@EntityGraph`
### 5.2 事务管理
- **声明式事务**`@Transactional` 注解配置
- **事务传播**:根据业务场景选择传播行为
- **只读事务**:查询操作使用 `readOnly = true`
- **事务超时**:设置合理的超时时间
### 5.3 数据库连接管理
- **连接池配置**:最大连接数、超时设置、健康检查
- **多数据源**:主从分离、分库分表支持
- **连接泄漏检测**:监控长时间占用的连接
- **数据库监控**:连接数、慢查询、死锁检测
### 5.4 数据访问安全
- **参数化查询**:防止 SQL 注入
- **数据脱敏**:敏感数据加密存储
- **访问控制**:数据库用户权限最小化
- **审计日志**:记录数据变更操作
## 6. API 设计模块RESTful
### 6.1 URL 设计规范
- **资源命名**:使用名词复数形式,避免动词
- **层次结构**:体现资源间的关系
- **版本控制**URL 路径或请求头中包含版本信息
- **查询参数**:过滤、排序、分页使用查询参数
### 6.2 HTTP 方法使用
- **GET**:获取资源,幂等操作
- **POST**:创建资源,非幂等操作
- **PUT**:完整更新资源,幂等操作
- **PATCH**:部分更新资源
- **DELETE**:删除资源,幂等操作
### 6.3 响应设计
- **状态码**:正确使用 HTTP 状态码
- **响应格式**:统一的 JSON 响应结构
- **错误处理**:标准化错误响应格式
- **分页响应**:包含总数、页码、页大小信息
### 6.4 API 文档和测试
- **OpenAPI 规范**:使用 Swagger 生成文档
- **接口测试**:单元测试、集成测试、契约测试
- **版本兼容**:向后兼容性保证
- **性能测试**:接口响应时间和并发测试
## 7. 异常处理模块
### 7.1 异常分类
- **业务异常**:可预期的业务逻辑异常
- **系统异常**:不可预期的技术异常
- **验证异常**:参数校验失败异常
- **外部服务异常**:第三方服务调用异常
### 7.2 异常处理策略
- **全局异常处理**:使用 `@ControllerAdvice` 统一处理
- **异常转换**:将底层异常转换为业务异常
- **异常日志**:记录异常堆栈和上下文信息
- **用户友好**:返回用户可理解的错误信息
### 7.3 异常响应格式
- **错误码**:业务错误码和 HTTP 状态码
- **错误信息**:简洁明了的错误描述
- **详细信息**:开发环境提供详细错误信息
- **请求追踪**:包含请求 ID 便于问题定位
### 7.4 异常监控
- **异常统计**:异常类型、频率统计
- **告警机制**:异常阈值告警
- **异常分析**:定期分析异常趋势
- **异常恢复**:自动重试和降级策略
## 8. 测试模块
### 8.1 测试分层策略
- **单元测试**:测试单个类或方法,使用 Mock
- **集成测试**:测试组件间交互,使用 TestContainers
- **端到端测试**:完整业务流程测试
- **性能测试**:负载测试、压力测试
### 8.2 测试工具和框架
- **JUnit 5**:测试框架,支持参数化测试
- **Mockito**Mock 框架,模拟依赖对象
- **TestContainers**:集成测试中使用真实数据库
- **WireMock**:模拟外部 HTTP 服务
### 8.3 测试数据管理
- **测试数据隔离**:每个测试独立的数据环境
- **数据准备**:使用 `@Sql` 或 Builder 模式
- **数据清理**:测试后清理数据,避免影响其他测试
- **测试数据工厂**:统一的测试数据创建
### 8.4 测试质量保证
- **代码覆盖率**:目标覆盖率 80% 以上
- **测试命名**:清晰的测试方法命名
- **断言明确**:使用有意义的断言消息
- **测试维护**:定期更新和重构测试代码
## 9. 日志记录模块
### 9.1 日志级别管理
- **ERROR**:系统错误,需要立即处理
- **WARN**:警告信息,需要关注
- **INFO**:重要业务信息,正常流程记录
- **DEBUG**:调试信息,开发环境使用
### 9.2 日志内容规范
- **结构化日志**:使用 JSON 格式,便于解析
- **上下文信息**:包含用户 ID、请求 ID、业务标识
- **敏感信息**:避免记录密码、身份证等敏感数据
- **性能信息**:记录关键操作的执行时间
### 9.3 日志输出配置
- **控制台输出**:开发环境使用,格式化显示
- **文件输出**:生产环境使用,按日期滚动
- **远程日志**:集中式日志收集,如 ELK Stack
- **日志压缩**:历史日志压缩存储
### 9.4 日志监控和分析
- **日志聚合**:统一收集和存储
- **实时监控**:关键错误实时告警
- **日志分析**:业务指标分析、异常趋势分析
- **日志检索**:快速定位问题日志
## 10. 应用监控模块
### 10.1 Spring Boot Actuator
- **端点配置**:暴露必要的监控端点
- **健康检查**:自定义健康指示器
- **指标收集**JVM、应用、业务指标
- **信息端点**:应用版本、构建信息
### 10.2 自定义监控
- **业务指标**:使用 Micrometer 收集业务数据
- **性能监控**:方法执行时间、数据库查询性能
- **错误监控**:异常统计和分析
- **用户行为**:关键业务操作追踪
### 10.3 日志与监控集成
- **结构化日志**:便于监控系统解析
- **关键事件记录**:业务关键节点日志
- **性能日志**:慢操作和资源使用情况
- **告警配置**:基于日志和指标的告警
### 10.4 生产环境监控
- **应用状态**:启动、运行、关闭状态监控
- **资源使用**内存、CPU、线程池状态
- **外部依赖**:数据库、缓存、第三方服务状态
- **业务监控**:核心业务指标实时监控
## 11. 代码质量模块
### 11.1 编码规范
- **命名规范**:类名、方法名、变量名清晰表达意图
- **代码结构**:合理的包结构和类层次
- **注释规范**:必要的类和方法注释
- **代码复用**:避免重复代码,提取公共方法
### 11.2 设计原则
- **SOLID 原则**:单一职责、开闭原则等
- **DRY 原则**:不重复自己
- **KISS 原则**:保持简单
- **YAGNI 原则**:你不会需要它
### 11.3 代码审查
- **Pull Request**:代码合并前必须审查
- **审查清单**:功能、性能、安全、可维护性
- **自动化检查**:静态代码分析工具
- **知识分享**:通过代码审查传播最佳实践
### 11.4 重构策略
- **持续重构**:小步快跑,持续改进
- **测试保护**:重构前确保测试覆盖
- **重构时机**:新功能开发时同步重构
- **技术债务**:定期评估和偿还技术债务

View File

@@ -0,0 +1,16 @@
---
description: 该规则解释了 SwiftUI 在 iOS、macOS、watchOS 和 tvOS 开发中的模式和最佳实践。
globs: **/*.swift
alwaysApply: false
---
# SwiftUI 规则
- 使用结构体struct创建视图并保持其小巧和专注
- 使用 @State 管理简单的视图本地状态
- 使用带有 @Published 的 @ObservableObject 管理共享状态
- 使用 @Binding 将可变状态传递给子视图
- 创建自定义 ViewModifiers 实现可复用的样式
- 使用环境对象environment objects进行依赖注入
- 对大型集合使用 LazyVStack 和 LazyHStack
- 将复杂的视图逻辑提取到单独的组件中

View File

@@ -0,0 +1,50 @@
---
description: 该规则解释了 Tailwind CSS 约定、实用工具类和现代 UI 开发的最佳实践。
globs: **/*.css
alwaysApply: false
---
# Tailwind CSS 规则
- 使用响应式前缀实现移动优先设计:
```html
<div class="w-full md:w-1/2 lg:w-1/3">
<!-- 移动设备上全宽,中等屏幕上占一半,大屏幕上占三分之一 -->
</div>
```
- 为交互元素使用状态变体:
```html
<button class="bg-blue-500 hover:bg-blue-600 focus:ring-2">
点击我
</button>
```
- 必要时使用 @apply 处理重复模式:
```css
@layer components {
.btn-primary {
@apply px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600;
}
}
```
- 对特定需求使用任意值:
```html
<div class="top-[117px] grid-cols-[1fr_2fr]">
<!-- 自定义定位和网格布局 -->
</div>
```
- 使用间距工具实现一致的布局:
```html
<div class="space-y-4">
<div>项目 1</div>
<div>项目 2</div>
</div>
```

View File

@@ -0,0 +1,87 @@
---
description: Vue.js 编码规则和最佳实践
globs: **/*.vue
alwaysApply: false
---
# Vue.js 规则
## 组件结构
- 使用组合式 API 而非选项式 API
- 保持组件小巧且专注
- 正确集成 TypeScript
- 实现适当的 props 验证
- 使用正确的 emit 声明
- 保持模板逻辑简洁
## 组合式 API
- 正确使用 ref 和 reactive
- 实现适当的生命周期钩子
- 使用 composables 实现可复用逻辑
- 保持 setup 函数整洁
- 正确使用计算属性
- 实现适当的侦听器
## 状态管理
- 使用 Pinia 进行状态管理
- 保持 stores 模块化
- 使用适当的状态组合
- 实现适当的 actions
- 正确使用 getters
- 适当处理异步状态
## 性能
- 正确使用组件懒加载
- 实现适当的缓存
- 正确使用计算属性
- 避免不必要的侦听器
- 正确使用 v-show 与 v-if
- 实现适当的 key 管理
## 路由
- 正确使用 Vue Router
- 实现适当的导航守卫
- 正确使用路由元字段
- 适当处理路由参数
- 实现适当的懒加载
- 使用适当的导航方法
## 表单
- 正确使用 v-model
- 实现适当的验证
- 适当处理表单提交
- 显示适当的加载状态
- 使用适当的错误处理
- 实现适当的表单重置
## TypeScript 集成
- 使用适当的组件类型定义
- 实现适当的 prop 类型
- 使用适当的 emit 声明
- 处理适当的类型推断
- 使用适当的 composable 类型
- 实现适当的 store 类型
## 测试
- 编写适当的单元测试
- 实现适当的组件测试
- 正确使用 Vue Test Utils
- 适当测试 composables
- 实现适当的模拟
- 测试异步操作
## 最佳实践
- 遵循 Vue 风格指南
- 使用适当的命名约定
- 保持组件组织有序
- 实现适当的错误处理
- 使用适当的事件处理
- 为复杂逻辑编写文档
## 构建和工具
- 使用 Vite 进行开发
- 配置适当的构建设置
- 正确使用环境变量
- 实现适当的代码分割
- 使用适当的资源处理
- 配置适当的优化

View File

@@ -0,0 +1,73 @@
---
description: c++ 编码规则和最佳实践。
globs: **/*.cpp, **/*.hpp
alwaysApply: false
---
# C++ 规则
你是一位精通现代 C++ (C++17/20)、STL 和系统级编程的高级 C++ 开发者。
## 代码风格和结构
- 编写简洁、符合习惯的 C++ 代码,提供准确的示例。
- 遵循现代 C++ 约定和最佳实践。
- 根据需要适当使用面向对象、过程式或函数式编程模式。
- 利用 STL 和标准算法进行集合操作。
- 使用描述性的变量和方法名称(例如,'isUserSignedIn''calculateTotal')。
- 将文件结构化为头文件(*.hpp和实现文件*.cpp并进行合理的关注点分离。
## 命名约定
- 类名使用 PascalCase。
- 变量名和方法使用 camelCase。
- 常量和宏使用 SCREAMING_SNAKE_CASE。
- 成员变量前缀使用下划线或 m_例如`_userId``m_userId`)。
- 使用命名空间逻辑地组织代码。
## C++ 特性使用
- 优先使用现代 C++ 特性例如auto、基于范围的循环、智能指针
- 使用 `std::unique_ptr` 和 `std::shared_ptr` 进行内存管理。
- 优先使用 `std::optional`、`std::variant` 和 `std::any` 作为类型安全的替代方案。
- 使用 `constexpr` 和 `const` 优化编译时计算。
- 使用 `std::string_view` 进行只读字符串操作,避免不必要的复制。
## 语法和格式
- 遵循一致的编码风格,如 Google C++ 风格指南或团队标准。
- 控制结构和方法的大括号放在同一行。
- 使用清晰一致的注释实践。
## 错误处理和验证
- 使用异常进行错误处理(例如,`std::runtime_error``std::invalid_argument`)。
- 使用 RAII 进行资源管理,避免内存泄漏。
- 在函数边界验证输入。
- 使用日志库记录错误例如spdlog、Boost.Log
## 性能优化
- 避免不必要的堆分配;尽可能优先使用基于栈的对象。
- 使用 `std::move` 启用移动语义并避免拷贝。
- 使用 `<algorithm>` 中的算法优化循环(例如,`std::sort``std::for_each`)。
- 使用 Valgrind 或 Perf 等工具分析和优化关键部分。
## 关键约定
- 使用智能指针而非原始指针以提高内存安全性。
- 避免全局变量;谨慎使用单例模式。
- 使用 `enum class` 实现强类型枚举。
- 在类中分离接口和实现。
- 明智地使用模板和元编程来实现通用解决方案。
## 测试
- 使用 Google Test (GTest) 或 Catch2 等框架编写单元测试。
- 使用 Google Mock 等库模拟依赖。
- 为系统组件实现集成测试。
## 安全性
- 使用安全编码实践避免漏洞(例如,缓冲区溢出、悬挂指针)。
- 优先使用 `std::array` 或 `std::vector` 而非原始数组。
- 避免 C 风格的类型转换;必要时使用 `static_cast`、`dynamic_cast` 或 `reinterpret_cast`。
- 在函数和成员变量中强制实施常量正确性。
## 文档
- 为类、方法和关键逻辑编写清晰的注释。
- 使用 Doxygen 生成 API 文档。
- 记录代码的假设、约束和预期行为。
遵循官方 ISO C++ 标准和指南,获取现代 C++ 开发的最佳实践。

View File

@@ -0,0 +1,275 @@
---
description: CSS 和样式规范
globs: *.css, *.scss, *.less, *.styled.ts
alwaysApply: false
---
# CSS 和样式规范
## 样式架构原则
- **组件化样式**:每个组件的样式应该封装在组件内部
- **样式隔离**避免全局样式污染使用CSS-in-JS或CSS Modules
- **主题一致性**:使用设计系统和主题变量保持视觉一致性
- **响应式设计**:优先考虑移动端,采用移动优先的响应式设计
- **性能优化**:避免不必要的样式重绘和重排
## Styled Components 规范
- **组件命名**:使用描述性的组件名,以 `Styled` 开头
```typescript
const StyledCard = styled.div`
padding: 16px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
`;
```
- **主题使用**:通过 `theme` 属性访问主题变量
```typescript
const StyledButton = styled.button`
background-color: ${({ theme }) => theme.colors.primary};
color: ${({ theme }) => theme.colors.white};
`;
```
- **条件样式**:使用 props 进行条件样式设置
```typescript
const StyledButton = styled.button<{ variant: 'primary' | 'secondary' }>`
background-color: ${({ variant, theme }) =>
variant === 'primary' ? theme.colors.primary : theme.colors.secondary
};
`;
```
- **样式继承**:合理使用样式继承减少重复代码
```typescript
const BaseButton = styled.button`
padding: 8px 16px;
border-radius: 4px;
border: none;
`;
const PrimaryButton = styled(BaseButton)`
background-color: ${({ theme }) => theme.colors.primary};
`;
```
## Ant Design 定制规范
- **主题定制**:使用 ConfigProvider 进行全局主题定制
```typescript
const theme = {
token: {
colorPrimary: '#1890ff',
borderRadius: 6,
fontSize: 14,
},
};
```
- **组件样式覆盖**:使用 CSS-in-JS 覆盖 Ant Design 组件样式
```typescript
const StyledTable = styled(Table)`
.ant-table-thead > tr > th {
background-color: #fafafa;
font-weight: 600;
}
`;
```
- **自定义组件**:基于 Ant Design 组件创建自定义组件
```typescript
const CustomCard = styled(Card)`
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
`;
```
## 响应式设计规范
- **断点定义**:使用标准断点进行响应式设计
```typescript
const breakpoints = {
xs: '480px',
sm: '576px',
md: '768px',
lg: '992px',
xl: '1200px',
xxl: '1600px',
};
```
- **媒体查询**:使用 CSS-in-JS 编写媒体查询
```typescript
const ResponsiveContainer = styled.div`
padding: 16px;
@media (min-width: ${({ theme }) => theme.breakpoints.md}) {
padding: 24px;
}
`;
```
- **Flex布局**:优先使用 Flexbox 进行布局
```typescript
const FlexContainer = styled.div`
display: flex;
flex-direction: column;
gap: 16px;
@media (min-width: ${({ theme }) => theme.breakpoints.md}) {
flex-direction: row;
}
`;
```
## 颜色和主题规范
- **颜色系统**:定义完整的颜色系统
```typescript
const colors = {
primary: '#1890ff',
success: '#52c41a',
warning: '#faad14',
error: '#ff4d4f',
text: {
primary: '#262626',
secondary: '#595959',
disabled: '#bfbfbf',
},
background: {
primary: '#ffffff',
secondary: '#fafafa',
disabled: '#f5f5f5',
},
};
```
- **暗色主题**:支持暗色主题切换
```typescript
const darkTheme = {
colors: {
primary: '#1890ff',
background: {
primary: '#141414',
secondary: '#1f1f1f',
},
text: {
primary: '#ffffff',
secondary: '#a6a6a6',
},
},
};
```
## 动画和过渡规范
- **过渡效果**:为交互元素添加适当的过渡效果
```typescript
const AnimatedButton = styled.button`
transition: all 0.3s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
`;
```
- **加载动画**:使用 CSS 动画创建加载效果
```typescript
const LoadingSpinner = styled.div`
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
animation: spin 1s linear infinite;
`;
```
## 布局规范
- **网格系统**:使用 CSS Grid 或 Flexbox 创建网格布局
```typescript
const GridContainer = styled.div`
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 24px;
`;
```
- **间距系统**:使用统一的间距系统
```typescript
const spacing = {
xs: '4px',
sm: '8px',
md: '16px',
lg: '24px',
xl: '32px',
xxl: '48px',
};
```
## 字体和排版规范
- **字体系统**:定义完整的字体系统
```typescript
const typography = {
fontFamily: {
primary: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto',
mono: '"SFMono-Regular", Consolas, "Liberation Mono", Menlo',
},
fontSize: {
xs: '12px',
sm: '14px',
md: '16px',
lg: '18px',
xl: '20px',
xxl: '24px',
},
fontWeight: {
normal: 400,
medium: 500,
semibold: 600,
bold: 700,
},
};
```
- **行高和字间距**:设置合适的行高和字间距
```typescript
const TextComponent = styled.p`
line-height: 1.6;
letter-spacing: 0.02em;
`;
```
## 性能优化规范
- **CSS优化**:避免深层嵌套和复杂选择器
- **重绘重排**:避免频繁的样式变更导致的重绘重排
- **CSS-in-JS优化**:使用 `shouldForwardProp` 避免不必要的 DOM 属性
```typescript
const StyledDiv = styled.div.withConfig({
shouldForwardProp: (prop) => !['customProp'].includes(prop),
})<{ customProp: boolean }>`
color: ${({ customProp }) => customProp ? 'red' : 'blue'};
`;
```
## 可访问性规范
- **对比度**:确保文本和背景有足够的对比度
- **焦点状态**:为可交互元素提供清晰的焦点状态
```typescript
const AccessibleButton = styled.button`
&:focus {
outline: 2px solid ${({ theme }) => theme.colors.primary};
outline-offset: 2px;
}
`;
```
- **语义化**:使用语义化的 HTML 元素和 ARIA 属性
## 代码组织规范
- **文件结构**:样式文件与组件文件放在同一目录
- **样式分离**:将复杂的样式逻辑提取到单独的样式文件
- **主题文件**:将主题相关的配置集中管理
- **工具函数**:创建样式工具函数提高复用性
```typescript
const getSpacing = (size: keyof typeof spacing) => spacing[size];
const getColor = (color: string) => ({ theme }: { theme: any }) => theme.colors[color];
```

View File

@@ -0,0 +1,36 @@
---
description: golang 编码规则和最佳实践。
globs: **/*.go
alwaysApply: false
---
# Golang 规则
你是一位专业的AI编程助手专门使用Go标准库的net/http包和Go 1.22中新引入的ServeMux构建API。
始终使用最新稳定版本的Go1.22或更新版本并熟悉RESTful API设计原则、最佳实践和Go语言惯用法。
- 严格按照用户的要求一丝不苟地执行。
- 首先逐步思考 - 详细描述你的API结构、端点和数据流计划以伪代码的形式详细写出。
- 确认计划后,开始编写代码!
- 为API编写正确、最新、无bug、功能完整、安全且高效的Go代码。
- 使用标准库的net/http包进行API开发
- 利用Go 1.22中新引入的ServeMux进行路由
- 正确处理不同的HTTP方法GET、POST、PUT、DELETE等
- 使用适当签名的方法处理器例如func(w http.ResponseWriter, r *http.Request)
- 在路由中利用通配符匹配和正则表达式支持等新特性
- 实现适当的错误处理,包括在有益时使用自定义错误类型。
- 使用适当的状态码并正确格式化JSON响应。
- 为API端点实现输入验证。
- 在有利于API性能时利用Go的内置并发特性。
- 遵循RESTful API设计原则和最佳实践。
- 包含必要的导入、包声明和任何所需的设置代码。
- 使用标准库的log包或简单的自定义日志记录器实现适当的日志记录。
- 考虑为横切关注点实现中间件(例如,日志记录、身份验证)。
- 在适当时实现速率限制和认证/授权,使用标准库功能或简单的自定义实现。
- 在API实现中不留todos、占位符或缺失部分。
- 在解释时保持简洁但为复杂逻辑或Go特定惯用法提供简短注释。
- 如果对最佳实践或实现细节不确定,请说明而不是猜测。
- 使用Go的testing包提供测试API端点的建议。
在API设计和实现中始终优先考虑安全性、可扩展性和可维护性。利用Go标准库的强大和简洁创建高效且符合语言习惯的API。

View File

@@ -0,0 +1,188 @@
---
description: 该规则解释了 Java 的约定和最佳实践。
globs: **/*.java
alwaysApply: false
---
# Java 语言规范
## Java 21 特性使用
- **Record类**:用于不可变数据传输对象
```java
public record UserInfo(String name, String email, LocalDateTime createdAt) {}
```
- **Pattern Matching**在switch表达式中使用模式匹配
```java
public String formatValue(Object value) {
return switch (value) {
case String s -> "String: " + s;
case Integer i -> "Number: " + i;
case null -> "null value";
default -> "Unknown: " + value.toString();
};
}
```
- **Text Blocks**用于多行字符串特别是SQL和JSON
```java
String sql = """
SELECT u.name, u.email
FROM users u
WHERE u.status = 'ACTIVE'
ORDER BY u.created_at DESC
""";
```
- **Sealed Classes**:用于受限的类层次结构
```java
public sealed class Result<T> permits Success, Error {
// 基类定义
}
public final class Success<T> extends Result<T> {
private final T data;
// 实现
}
```
- **Virtual Threads**:用于高并发场景
```java
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(() -> {
// 高并发任务
});
}
```
## 命名约定
- **类名**:使用帕斯卡命名法(如 `UserController`、`OrderService`
- **方法和变量名**:使用驼峰命名法(如 `findUserById`、`isOrderValid`
- **常量**:使用全大写下划线分隔(如 `MAX_RETRY_ATTEMPTS`、`DEFAULT_PAGE_SIZE`
- **包名**:使用小写,按功能模块划分(如 `com.example.user.domain`
## 代码风格
- **缩进**使用4个空格不使用Tab
- **行长度**每行不超过120个字符
- **大括号**使用Egyptian风格开括号不换行
- **空行**:方法间使用一个空行分隔,逻辑块间使用空行分隔
## 异常处理
- **检查异常**:谨慎使用检查异常,优先使用运行时异常
- **异常链**:保持异常链,不丢失原始异常信息
```java
try {
// 可能抛出异常的代码
} catch (SpecificException e) {
throw new BusinessException("业务处理失败", e);
}
```
- **资源管理**使用try-with-resources自动管理资源
```java
try (var reader = Files.newBufferedReader(path)) {
// 使用reader
}
```
## 集合和流处理
- **集合选择**:根据使用场景选择合适的集合类型
- `ArrayList`:随机访问频繁
- `LinkedList`:插入删除频繁
- `HashMap`:键值对存储
- `TreeMap`:需要排序的键值对
- **Stream API**充分利用Stream API进行函数式编程
```java
List<String> activeUserNames = users.stream()
.filter(user -> user.isActive())
.map(User::getName)
.sorted()
.toList();
```
## 并发编程
- **线程安全**:优先使用不可变对象和线程安全的集合
- **锁机制**合理使用synchronized、ReentrantLock等锁机制
- **并发集合**使用ConcurrentHashMap、CopyOnWriteArrayList等并发集合
- **CompletableFuture**使用CompletableFuture处理异步操作
```java
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> fetchData())
.thenApply(data -> processData(data))
.exceptionally(throwable -> "默认值");
```
## 内存管理
- **对象创建**:避免在循环中创建不必要的对象
- **字符串处理**大量字符串操作使用StringBuilder
- **集合大小**:预估集合大小,避免频繁扩容
- **弱引用**适当使用WeakReference避免内存泄漏
## 泛型使用
- **类型安全**:充分利用泛型提供类型安全
- **通配符**:正确使用上界通配符(? extends和下界通配符? super
- **类型擦除**:理解泛型类型擦除的限制
```java
public <T extends Comparable<T>> T findMax(List<T> list) {
return list.stream().max(Comparable::compareTo).orElse(null);
}
```
## 注解使用
- **标准注解**:正确使用@Override、@Deprecated、@SuppressWarnings等
- **自定义注解**:合理创建自定义注解简化代码
- **注解处理**:了解编译时和运行时注解处理
## 测试规范
- **单元测试**使用JUnit 5编写单元测试
- **测试命名**:测试方法使用描述性命名(如 `shouldReturnUserWhenValidIdProvided`
- **断言**使用AssertJ提供更好的断言体验
```java
@Test
void shouldCalculateCorrectTotal() {
// Given
List<Item> items = List.of(
new Item("item1", 10.0),
new Item("item2", 20.0)
);
// When
double total = calculator.calculateTotal(items);
// Then
assertThat(total).isEqualTo(30.0);
}
```
## 性能优化
- **算法复杂度**:选择合适的算法和数据结构
- **缓存策略**:合理使用缓存减少重复计算
- **懒加载**:对于昂贵的操作使用懒加载
- **批量处理**:批量处理数据库操作和网络请求
## 代码质量
- **单一职责**:每个类和方法只负责一个功能
- **开闭原则**:对扩展开放,对修改关闭
- **依赖倒置**:依赖抽象而不是具体实现
- **接口隔离**:使用小而专一的接口
- **代码复用**:提取公共逻辑,避免重复代码
## 文档和注释
- **JavaDoc**为公共API编写完整的JavaDoc
- **代码注释**:为复杂逻辑添加解释性注释
- **TODO标记**使用TODO标记待完成的工作
```java
/**
* 计算用户积分
*
* @param userId 用户ID
* @param actions 用户行为列表
* @return 计算得出的积分值
* @throws UserNotFoundException 当用户不存在时抛出
*/
public int calculatePoints(Long userId, List<UserAction> actions) {
// TODO: 实现积分计算逻辑
return 0;
}
```

View File

@@ -0,0 +1,120 @@
---
description: Kotlin 开发约定和最佳实践
globs: **/*.kt
alwaysApply: false
---
## Kotlin 开发规范
### 基本原则
- 优先使用类型推断,必要时显式声明类型提高可读性
- 避免使用 `Any`,创建具体的类型定义
- 优先使用 `val` 而非 `var`,保持不可变性
- 使用 Kotlin 的空安全特性,避免显式 null 检查
- 避免魔法数字,定义有意义的常量
### 命名规范
- **类和接口**PascalCase (`UserRepository`, `PaymentService`)
- **函数和变量**camelCase (`getUserById`, `isValid`)
- **常量和枚举值**UPPER_SNAKE_CASE (`MAX_RETRY_COUNT`, `DEFAULT_TIMEOUT`)
- **包名**:全小写,使用点分隔 (`com.example.userservice`)
- **文件名**PascalCase与主要类名一致
- **布尔变量**:使用 `is`、`has`、`can`、`should` 前缀 (`isLoading`, `hasPermission`, `canDelete`)
- 使用完整单词而非缩写,确保拼写正确
- 标准缩写除外API、URL、HTTP、JSON 等
- 常见缩写id、ctx、req、res
### 函数设计
- 编写简短且单一目的的函数(建议 ≤20 行)
- 使用表达式函数简化单行返回:`fun square(x: Int) = x * x`
- 函数名以动词开头,体现其行为
- 优先使用高阶函数和扩展函数
- 使用命名参数提高可读性:`createUser(name = "John", age = 25)`
- 合理使用默认参数值,减少函数重载
- 通过早期返回和提取工具函数避免深层嵌套
- 使用单一抽象级别原则
### 类和数据结构
- **数据类**:用于纯数据承载,自动生成 `equals`、`hashCode`、`toString`
- **密封类**:用于有限状态表示,替代枚举的复杂场景
- **密封接口**Kotlin 1.5+ 用于更灵活的类型层次
- **对象类**:用于单例模式和工具类
- **内联类**:用于类型安全的原始类型包装
- 优先使用组合而非继承
- 遵循 SOLID 原则
- 保持类的职责单一,避免过大的类(建议 ≤200 行≤10 个公共方法)
- 不要滥用原始类型,将相关数据封装在复合类型中
### 空安全和错误处理
- 使用 `?.` 安全调用操作符
- 使用 `?:` Elvis 操作符提供默认值
- 使用 `!!` 操作符需要有充分理由并添加注释
- 优先使用 `Result` 类型处理可能失败的操作
- 对于异常情况使用具体的异常类型而非通用异常
- 避免在函数中进行数据验证,使用具有内部验证的类型
### 协程和异步编程
- 使用 `suspend` 函数处理异步操作
- 在合适的作用域中启动协程 (`viewModelScope`, `lifecycleScope`, `runBlocking`)
- 使用 `Flow` 处理数据流,`StateFlow`/`SharedFlow` 处理状态
- 避免 `GlobalScope`,始终使用结构化并发
- 合理使用协程上下文和调度器
- 使用 `async`/`await` 进行并发操作
- 正确处理协程取消和异常
### 集合和函数式编程
- 优先使用不可变集合 (`listOf`, `setOf`, `mapOf`)
- 使用函数式操作:`map`、`filter`、`reduce`、`fold`
- 合理使用序列 (`Sequence`) 处理大数据集或链式操作
- 使用作用域函数:`let`、`run`、`with`、`apply`、`also`
- 使用 `takeIf`、`takeUnless` 进行条件处理
- 对简单 lambda 使用 `it` 参数,复杂情况使用命名参数
### 泛型和类型系统
- 合理使用泛型约束和变型(`in`、`out`
- 使用 `reified` 参数访问泛型类型信息
- 利用类型别名提高代码可读性:`typealias UserId = String`
- 使用内联函数优化高阶函数性能
### 可见性和封装
- 使用最小必要的可见性修饰符
- 优先使用 `internal` 而非 `public` 用于模块内部 API
- 使用 `private` 限制类内部实现细节
- 合理使用 `protected` 用于继承场景
### 测试规范
- 测试方法使用描述性命名:`should_return_user_when_valid_id_provided`
- 遵循 Arrange-Act-Assert 模式
- 清楚命名测试变量:`given...`、`when...`、`then...` 或 `input...`、`expected...`、`actual...`
- 为每个公共函数编写单元测试
- 使用测试替身Mock、Stub模拟依赖
- 为每个模块编写集成测试
- 遵循 Given-When-Then 约定编写行为测试
### 代码组织和架构
- 按功能而非类型组织包结构
- 将相关的类放在同一文件中(如密封类的子类)
- 合理使用扩展函数增强现有类型
- 声明接口定义契约,面向接口编程
- 使用依赖注入提高代码可测试性
- 遵循领域驱动设计原则
### 性能和资源管理
- 使用 `inline` 关键字优化高阶函数
- 合理使用 `lazy` 延迟初始化
- 注意避免内存泄漏,特别是在协程和回调中
- 使用 `use` 函数自动管理资源

View File

@@ -0,0 +1,20 @@
---
description: 该规则解释了 Python 编码、最佳实践、 整洁高效的代码模式.
globs: **/*.py
alwaysApply: false
---
# Python 规则
- 遵循 PEP 8 风格指南和命名约定
- 使用类型注解增强代码可读性和类型安全性
- 使用虚拟环境管理依赖:
- 优先使用 `venv` 或 `poetry` 进行环境隔离
- 使用 `requirements.txt` 或 `pyproject.toml` 记录依赖
- 使用上下文管理器处理资源(如文件操作)
- 优先使用列表推导式、生成器表达式和字典推导式
- 使用 `pytest` 进行测试,保持高测试覆盖率
- 使用文档字符串docstrings记录函数、类和模块
- 遵循面向对象设计原则SOLID
- 使用异常处理保证程序健壮性
- 使用 `dataclasses` 或 `pydantic` 模型表示数据

View File

@@ -0,0 +1,57 @@
---
description: TypeScript 编码规则和最佳实践
globs: **/*.ts, **/*.tsx, **/*.d.ts
---
# TypeScript 规则
## 类型系统
- 对于对象定义,优先使用接口而非类型
- 对于联合类型、交叉类型和映射类型,使用 type
- 避免使用 `any`,对于未知类型优先使用 `unknown`
- 使用严格的 TypeScript 配置
- 充分利用 TypeScript 的内置工具类型
- 使用泛型实现可复用的类型模式
## 命名约定
- 类型名称和接口使用 PascalCase
- 变量和函数使用 camelCase
- 常量使用 UPPER_CASE
- 使用带有辅助动词的描述性名称例如isLoading, hasError
- React props 的接口前缀使用 'Props'例如ButtonProps
## 代码组织
- 类型定义应靠近使用它们的地方
- 共享的类型和接口从专用类型文件导出
- 使用桶导出index.ts组织导出
- 将共享类型放在 `types` 目录中
- 组件 props 与其组件共同放置
## 函数
- 为公共函数使用显式返回类型
- 回调和方法使用箭头函数
- 实现带有自定义错误类型的适当错误处理
- 复杂类型场景使用函数重载
- 优先使用 async/await 而非 Promises
## 最佳实践
- 在 tsconfig.json 中启用严格模式
- 不可变属性使用 readonly
- 利用可辨识联合类型提高类型安全性
- 使用类型守卫进行运行时类型检查
- 实现适当的空值检查
- 避免不必要的类型断言
## 错误处理
- 为领域特定错误创建自定义错误类型
- 对可能失败的操作使用 Result 类型
- 实现适当的错误边界
- 使用带有类型化 catch 子句的 try-catch 块
- 正确处理 Promise 拒绝
## 模式
- 复杂对象创建使用构建者模式
- 数据访问实现仓储模式
- 对象创建使用工厂模式
- 利用依赖注入
- 使用模块模式实现封装

View File

@@ -0,0 +1,61 @@
---
description: 微信小程序 WXML 编写规范
globs: **/*.wxml
alwaysApply: false
---
# WXML 编写规范
## 基本语法规范
- 使用小写标签名和属性名
- 属性值必须用双引号包围
- 自闭合标签使用 `<tag />` 格式
- 保持标签的正确嵌套和闭合
- 合理使用缩进,保持代码层次清晰
## 数据绑定
- 使用 `{{}}` 进行数据绑定,表达式内避免复杂逻辑
- 布尔属性使用 `attr="{{condition}}"` 格式
- 事件绑定使用 `bind:` 或 `catch:` 前缀
- 避免在模板中进行复杂的数据处理,应在 JS 中预处理
## 条件渲染
- 简单条件使用 `wx:if`,复杂条件在 JS 中处理后绑定布尔值
- `wx:if` 与 `hidden` 的选择:频繁切换用 `hidden`,条件较少变化用 `wx:if`
- 多条件分支使用 `wx:if`、`wx:elif`、`wx:else`
- 避免过深的条件嵌套,考虑拆分为子组件
## 列表渲染
- 必须设置 `wx:key`,优先使用唯一标识符
- `wx:for-item` 和 `wx:for-index` 使用有意义的名称
- 避免在循环中嵌套复杂逻辑,考虑使用子组件
- 长列表考虑使用虚拟列表或分页加载
## 组件使用
- 组件标签名使用 kebab-case 格式
- 属性传递使用描述性名称
- 事件监听使用 `bind:` 前缀,事件名使用 kebab-case
- 合理使用 slot 进行内容分发
## 样式类名
- 类名使用 kebab-case 格式
- 避免使用内联样式,统一在 WXSS 中定义
- 使用 TDesign 提供的工具类和组件类名
- 自定义类名应具有语义化
## 性能优化
- 减少不必要的节点嵌套
- 合理使用 `wx:if` 和 `hidden` 控制渲染
- 避免在模板中使用复杂表达式
- 图片懒加载使用 `lazy-load` 属性
## 无障碍访问
- 为交互元素添加 `aria-label` 属性
- 使用语义化标签,如 `button`、`navigator` 等
- 确保键盘导航的可用性
- 为图片添加 `alt` 属性描述
## 代码组织
- 模板结构应与页面/组件的逻辑结构保持一致
- 相关的元素应当组织在一起
- 使用注释标记复杂的模板区块
- 保持模板的简洁性,复杂逻辑拆分为子组件

View File

@@ -0,0 +1,79 @@
---
description: 微信小程序 WXSS 编写规范
globs: **/*.wxss
alwaysApply: false
---
# WXSS 编写规范
## 基本语法规范
- 使用 2 个空格进行缩进
- 选择器和属性名使用小写字母
- 属性值后必须加分号
- 颜色值使用小写字母,优先使用简写形式
- 0 值不需要单位,如 `margin: 0` 而非 `margin: 0px`
## 选择器规范
- 类名使用 kebab-case 格式,如 `.user-info`
- 避免使用 ID 选择器,优先使用类选择器
- 避免过深的选择器嵌套(不超过 3 层)
- 使用有意义的类名,体现元素的功能而非样式
## 布局规范
- 优先使用 Flexbox 进行布局
- 使用 `rpx` 单位进行响应式设计
- 合理使用 `box-sizing: border-box`
- 避免使用绝对定位,除非必要
## 尺寸单位
- 字体大小使用 `rpx`,参考设计稿 750px 宽度
- 边距和内边距使用 `rpx`
- 边框宽度使用 `px`(通常为 1px
- 百分比用于相对布局
## 颜色和主题
- 使用 TDesign 提供的 CSS 变量
- 自定义颜色应定义为 CSS 变量
- 避免硬编码颜色值
- 支持深色模式时使用主题变量
## 字体规范
- 使用系统默认字体栈
- 字体大小遵循设计规范常用尺寸24rpx、28rpx、32rpx、36rpx
- 行高设置为字体大小的 1.4-1.6 倍
- 合理使用字重,避免过度使用粗体
## 组件样式
- 组件样式应当封装完整,避免依赖外部样式
- 使用 `externalClasses` 允许外部定制样式
- 避免样式污染,使用适当的选择器作用域
- 组件内部样式使用相对单位
## 动画和过渡
- 使用 CSS 过渡而非 JavaScript 动画
- 动画时长控制在 200-300ms
- 使用 `ease-out` 缓动函数
- 避免同时动画过多属性
## 响应式设计
- 使用 `rpx` 实现基本的响应式
- 考虑不同屏幕尺寸的适配
- 使用媒体查询处理特殊情况
- 测试在不同设备上的显示效果
## 性能优化
- 避免使用复杂的选择器
- 减少重绘和重排的样式属性
- 合理使用 `transform` 和 `opacity` 进行动画
- 避免使用 `!important`
## 代码组织
- 样式按功能模块组织
- 使用注释分隔不同的样式区块
- 公共样式提取到全局样式文件
- 保持样式文件的简洁和可读性
## TDesign 集成
- 优先使用 TDesign 提供的样式类
- 通过 CSS 变量定制主题
- 遵循 TDesign 的设计规范
- 避免覆盖组件库的核心样式

View File

@@ -0,0 +1,53 @@
---
description: markdown 文件编写规则
globs: *.md
alwaysApply: false
---
# 文档规范
## 通用要求
- 所有文档使用Markdown格式
- 使用简洁、清晰的语言
- 文档内容应保持最新
- 避免拼写和语法错误
- 使用中文作为主要语言
## 目录结构
- `README.md`:项目根目录,提供项目概述
- `docs/`:存放详细文档
- `guide/`:使用指南
- `api/`API文档
- `examples/`:示例代码文档
## README.md 内容规范
- 项目名称和简短描述
- 技术栈说明
- 项目结构说明
- 使用说明
- 许可证信息
## 版本记录规范
- 使用 `CHANGELOG.md` 记录版本变更
- 遵循语义化版本Semantic Versioning规范
- 每个版本应包含:新增功能、修复问题、破坏性变更
## 文档内容组织
- 从整体到局部,从简单到复杂
- 重要信息放在前面
- 相关内容应当放在一起
- 使用小标题和列表增强可读性
- 避免过长段落,保持内容简洁
## 代码示例规范
- 提供完整可运行的示例
- 代码应当简洁且易于理解
- 添加适当的注释解释关键部分
- 说明代码的预期输出或行为
- 更新示例以匹配最新API

View File

@@ -0,0 +1,56 @@
---
description: 辅助生成 git 提交信息
globs:
alwaysApply: false
---
# Git 规则
## 重要原则
- **重要**:不要自动提交 git 代码,除非有明确的提示
- 提交前确保代码通过所有测试
- 保持提交信息简洁明了,描述清楚变更内容
- 避免大型提交,尽量将变更分解为小的、相关的提交
## 提交规范
git 提交模板<type>(<scope>): <subject>,具体要求如下:
1. 注意冒号 : 后有空格
2. type 的枚举值有:
- feat: 新增功能
- fix: 修复 bug
- docs: 文档注释
- style: 代码格式(不影响代码运行的变动)
- refactor: 重构、优化(既不增加新功能, 也不是修复bug)
- perf: 性能优化
- test: 增加测试
- chore: 构建过程或辅助工具的变动
- revert: 回退
- build: 打包
3. 若 subject 中描述超过两种要点,请使用要点列表描述详情,每个要点使用-符号开头,多个换行,参考如下样例:
```
feat(web): implement email verification workflow
- Add email verification token generation service
- Create verification email template with dynamic links
- Add API endpoint for token validation
- Update user model with verification status field
```
## 分支管理
- main/master: 主分支,保持稳定可发布状态
- develop: 开发分支,包含最新开发特性
- feature/*: 功能分支,用于开发新功能
- bugfix/*: 修复分支用于修复bug
- release/*: 发布分支,用于准备发布
**常用分支命名约定**
| 分支类型 | 命名格式 | 示例 |
| ---------- | -------------------- | ------------------------- |
| 功能分支 | feature/[描述] | feature/user-auth |
| 修复分支 | fix/[问题ID]-[描述] | fix/issue-42-login-crash |
| 发布分支 | release/[版本] | release/v2.1.0 |
| 热修复分支 | hotfix/[版本]-[描述] | hotfix/v2.0.1-payment-fix |

View File

@@ -0,0 +1,114 @@
---
description: Gitflow 工作流规则
globs:
alwaysApply: false
---
# Gitflow 工作流规则
## 主分支
### main或master
- 包含生产就绪代码
- 永远不要直接提交到main分支
- 只接受来自以下分支的合并:
- hotfix/* 分支
- release/* 分支
- 每次合并后必须使用版本号标记
### develop
- 主开发分支
- 包含最新交付的开发变更
- 功能分支的源分支
- 永远不要直接提交到develop分支
## 支持分支
### feature/*
- 从develop分支创建
- 合并回develop
- 命名约定feature/[issue-id]-描述性名称
- 示例feature/123-user-authentication
- 创建PR前必须与develop分支保持同步
- 合并后删除
### release/*
- 从develop分支创建
- 合并回:
- main
- develop
- 命名约定release/vX.Y.Z
- 示例release/v1.2.0
- 仅进行bug修复、文档编写及与发布相关的任务
- 不添加新功能
- 合并后删除
### hotfix/*
- 从main分支创建
- 合并回:
- main
- develop
- 命名约定hotfix/vX.Y.Z
- 示例hotfix/v1.2.1
- 仅用于紧急生产环境修复
- 合并后删除
## 提交信息
- 格式:`type(scope): description`
- 类型:
- feat: 新功能
- fix: Bug修复
- docs: 文档变更
- style: 格式调整、缺失分号等
- refactor: 代码重构
- test: 添加测试
- chore: 维护任务
## 版本控制
### 语义化版本
- MAJOR版本用于不兼容的API变更
- MINOR版本用于向后兼容的功能性变更
- PATCH版本用于向后兼容的bug修复
## Pull Request规则
1. 所有变更必须通过Pull Request进行
2. 所需批准至少1个
3. CI检查必须通过
4. 不允许直接提交到受保护分支main, develop
5. 合并前分支必须保持最新
6. 合并后删除分支
## 分支保护规则
### main和develop
- 要求Pull Request审核
- 要求状态检查通过
- 要求分支保持最新
- 限制规则包括管理员
- 禁止强制推送
- 禁止删除
## 发布流程
1. 从develop创建release分支
2. 更新版本号
3. 修复任何与发布相关的问题
4. 创建PR到main
5. 合并到main后
- 标记发布
- 合并回develop
- 删除release分支
## 热修复流程
1. 从main创建hotfix分支
2. 修复问题
3. 更新patch版本号
4. 创建PR到main
5. 合并到main后
- 标记发布
- 合并回develop
- 删除hotfix分支

View File

@@ -98,7 +98,7 @@ app.use(JsonViewer);
app.use(BaiduMap, {
// ak 是在百度地图开发者平台申请的密钥 详见 http://lbsyun.baidu.com/apiconsole/key */
ak: 'SOawZTeQbxdgrKYYx0o2hn34G0DyU2uo', //
ak: 'fLz8UwJSM3ayYl6dtsWYp7TQ8993R6kC', //
// v: '2.0', // 默认使用3.0
// type: 'WebGL' // ||API 默认API (使用此模式 BMap=BMapGL)
// type: 'WebGL', // ||API 默认API (使用此模式 BMap=BMapGL)

View File

@@ -8,11 +8,13 @@
<el-table-column prop="licensePlate" label="车牌号" />
<el-table-column label="车身照片" prop="" width="160">
<template #default="scope">
<!-- 车头照片 -->
<el-image
v-if="scope.row.carFrontPhoto"
style="width: 50px; height: 50px; margin-right: 10px"
:src="scope.row.carFrontPhoto ? scope.row.carFrontPhoto : ''"
:src="scope.row.carFrontPhoto"
fit="cover"
:preview-src-list="[scope.row.carFrontPhoto] ? [scope.row.carFrontPhoto] : []"
:preview-src-list="[scope.row.carFrontPhoto]"
preview-teleported
>
<template #error>
@@ -24,11 +26,19 @@
</div>
</template>
</el-image>
<div
v-else
style="width: 50px; height: 50px; margin-right: 10px; display: inline-flex; justify-content: center; align-items: center; background: #f5f7fa; border-radius: 4px; color: #909399"
>
<el-icon style="font-size: 30px"><Picture /></el-icon>
</div>
<!-- 车尾照片 -->
<el-image
v-if="scope.row.carBehindPhoto"
style="width: 50px; height: 50px; margin-right: 10px"
:src="scope.row.carBehindPhoto ? scope.row.carBehindPhoto : ''"
:src="scope.row.carBehindPhoto"
fit="cover"
:preview-src-list="[scope.row.carBehindPhoto] ? [scope.row.carBehindPhoto] : []"
:preview-src-list="[scope.row.carBehindPhoto]"
preview-teleported
>
<template #error>
@@ -40,6 +50,12 @@
</div>
</template>
</el-image>
<div
v-else
style="width: 50px; height: 50px; margin-right: 10px; display: inline-flex; justify-content: center; align-items: center; background: #f5f7fa; border-radius: 4px; color: #909399"
>
<el-icon style="font-size: 30px"><Picture /></el-icon>
</div>
</template>
</el-table-column>
<el-table-column prop="startLocation" label="起始地" />

View File

@@ -518,7 +518,7 @@ const loadDeviceLogs = async (deviceId, deviceType, deliveryId) => {
const initMap = async () => {
try {
// 使用百度地图 API Key
const BMapGL = await BMPGL('SOawZTeQbxdgrKYYx0o2hn34G0DyU2uo');
const BMapGL = await BMPGL('fLz8UwJSM3ayYl6dtsWYp7TQ8993R6kC');
const lat = parseFloat(warningData.latitude);
const lon = parseFloat(warningData.longitude);

View File

@@ -15,11 +15,13 @@
<el-table-column label="车牌号" prop="licensePlate"> </el-table-column>
<el-table-column label="车身照片" prop="" width="160">
<template #default="scope">
<!-- 车头照片 -->
<el-image
v-if="scope.row.carFrontPhoto"
style="width: 50px; height: 50px; margin-right: 10px"
:src="scope.row.carFrontPhoto ? scope.row.carFrontPhoto : ''"
:src="scope.row.carFrontPhoto"
fit="cover"
:preview-src-list="[scope.row.carFrontPhoto] ? [scope.row.carFrontPhoto] : []"
:preview-src-list="[scope.row.carFrontPhoto]"
preview-teleported
>
<template #error>
@@ -31,11 +33,19 @@
</div>
</template>
</el-image>
<div
v-else
style="width: 50px; height: 50px; margin-right: 10px; display: inline-flex; justify-content: center; align-items: center; background: #f5f7fa; border-radius: 4px; color: #909399"
>
<el-icon style="font-size: 30px"><Picture /></el-icon>
</div>
<!-- 车尾照片 -->
<el-image
v-if="scope.row.carBehindPhoto"
style="width: 50px; height: 50px; margin-right: 10px"
:src="scope.row.carBehindPhoto ? scope.row.carBehindPhoto : ''"
:src="scope.row.carBehindPhoto"
fit="cover"
:preview-src-list="[scope.row.carBehindPhoto] ? [scope.row.carBehindPhoto] : []"
:preview-src-list="[scope.row.carBehindPhoto]"
preview-teleported
>
<template #error>
@@ -47,6 +57,12 @@
</div>
</template>
</el-image>
<div
v-else
style="width: 50px; height: 50px; margin-right: 10px; display: inline-flex; justify-content: center; align-items: center; background: #f5f7fa; border-radius: 4px; color: #909399"
>
<el-icon style="font-size: 30px"><Picture /></el-icon>
</div>
</template>
</el-table-column>
<el-table-column label="起始地" prop="startLocation"> </el-table-column>

View File

@@ -932,10 +932,22 @@ const fillFormWithEditData = (editData) => {
formData.endLat = delivery.endLat || '';
formData.endLon = delivery.endLon || '';
// 时间(需要处理)
// estimatedDeliveryTime 对应 estimatedArrivalTime
// 时间字段映射
// estimatedDepartureTime预计出发时间
if (delivery.estimatedDepartureTime) {
formData.estimatedDepartureTime = delivery.estimatedDepartureTime;
} else if (delivery.createTime) {
// 如果没有预计出发时间,使用创建时间作为默认值
formData.estimatedDepartureTime = delivery.createTime;
} else {
formData.estimatedDepartureTime = '';
}
// estimatedDeliveryTime 对应 estimatedArrivalTime预计送达时间
if (delivery.estimatedDeliveryTime) {
formData.estimatedArrivalTime = delivery.estimatedDeliveryTime;
} else {
formData.estimatedArrivalTime = '';
}
// 重量信息

View File

@@ -1,9 +1,10 @@
package com.aiotagro.cattletrade.business.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* 运送清单编辑DTO
@@ -45,4 +46,16 @@ public class DeliveryEditDto {
private String endLat;
private String endLon;
/**
* 预计出发时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date estimatedDepartureTime;
/**
* 预计到达时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date estimatedArrivalTime;
}

View File

@@ -165,6 +165,13 @@ public class Delivery implements Serializable {
@TableField("end_lon")
private String endLon;
/**
* 预计出发时间
*/
@TableField("estimated_departure_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date estimatedDepartureTime;
/**
* 预计送达时间
*/

View File

@@ -197,10 +197,16 @@ public class IotDeviceLogSyncService {
log.setYWalkSteps(device.getSameDaySteps().longValue());
}
if (device.getLatitude() != null) {
log.setLatitude(device.getLatitude());
String lat = sanitizeCoordinate(device.getLatitude());
if (lat != null) {
log.setLatitude(lat);
}
}
if (device.getLongitude() != null) {
log.setLongitude(device.getLongitude());
String lng = sanitizeCoordinate(device.getLongitude());
if (lng != null) {
log.setLongitude(lng);
}
}
// 设置时间字段
@@ -236,10 +242,16 @@ public class IotDeviceLogSyncService {
log.setYWalkSteps(device.getSameDaySteps().longValue());
}
if (device.getLatitude() != null) {
log.setLatitude(device.getLatitude());
String lat = sanitizeCoordinate(device.getLatitude());
if (lat != null) {
log.setLatitude(lat);
}
}
if (device.getLongitude() != null) {
log.setLongitude(device.getLongitude());
String lng = sanitizeCoordinate(device.getLongitude());
if (lng != null) {
log.setLongitude(lng);
}
}
// 设置时间字段
@@ -289,9 +301,10 @@ public class IotDeviceLogSyncService {
if (device.getLatitude() != null) {
// latitude是String类型直接使用
String latStr = device.getLatitude();
latStr = sanitizeCoordinate(latStr);
// 检查是否为无效坐标
if (!latStr.equals("0") && !latStr.trim().isEmpty() && !latStr.equals("null") && !latStr.equals("NULL")) {
if (latStr != null && !latStr.equals("0") && !latStr.trim().isEmpty() && !latStr.equals("null") && !latStr.equals("NULL")) {
hasValidLatitude = true;
log.setLatitude(latStr);
} else {
@@ -302,9 +315,10 @@ public class IotDeviceLogSyncService {
if (device.getLongitude() != null) {
// longitude是String类型直接使用
String lngStr = device.getLongitude();
lngStr = sanitizeCoordinate(lngStr);
// 检查是否为无效坐标
if (!lngStr.equals("0") && !lngStr.trim().isEmpty() && !lngStr.equals("null") && !lngStr.equals("NULL")) {
if (lngStr != null && !lngStr.equals("0") && !lngStr.trim().isEmpty() && !lngStr.equals("null") && !lngStr.equals("NULL")) {
hasValidLongitude = true;
log.setLongitude(lngStr);
} else {
@@ -328,6 +342,26 @@ public class IotDeviceLogSyncService {
return log;
}
/**
* 规范化经纬度字符串,移除首尾空格,限制最大长度,过滤无效字面量
*/
private String sanitizeCoordinate(String coord) {
if (coord == null) {
return null;
}
String v = coord.trim();
if (v.isEmpty()) {
return null;
}
if ("null".equalsIgnoreCase(v)) {
return null;
}
// 限长,避免超过数据库字段长度
if (v.length() > 32) {
v = v.substring(0, 32);
}
return v;
}
/**
* 获取设备日志同步统计信息
*/

View File

@@ -16,7 +16,6 @@ import com.aiotagro.common.core.utils.DateUtils;
import com.aiotagro.common.core.utils.EnumUtil;
import com.aiotagro.common.core.utils.SecurityUtil;
import com.aiotagro.common.core.utils.StringUtils;
import com.aiotagro.common.core.constant.RoleConstants;
import com.aiotagro.common.core.web.domain.AjaxResult;
import com.aiotagro.common.core.web.domain.PageResultResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -24,7 +23,6 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
@@ -225,8 +223,30 @@ public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> i
delivery.setDriverName(driverName);
}
// 处理车身照片分割
if (carImg != null && !carImg.isEmpty()) {
// 优先从车辆表获取车身照片(根据车牌号)
// 如果车辆表中没有,再从司机信息中获取作为后备
boolean vehiclePhotoSet = false;
if (delivery.getLicensePlate() != null && StringUtils.isNotEmpty(delivery.getLicensePlate())) {
try {
Vehicle vehicle = vehicleMapper.selectByLicensePlate(delivery.getLicensePlate());
if (vehicle != null) {
String carFrontPhoto = vehicle.getCarFrontPhoto();
String carRearPhoto = vehicle.getCarRearPhoto();
if (StringUtils.isNotEmpty(carFrontPhoto) || StringUtils.isNotEmpty(carRearPhoto)) {
delivery.setCarFrontPhoto(StringUtils.isNotEmpty(carFrontPhoto) ? carFrontPhoto : null);
delivery.setCarBehindPhoto(StringUtils.isNotEmpty(carRearPhoto) ? carRearPhoto : null);
vehiclePhotoSet = true;
logger.debug("从车辆表获取照片: 车牌号={}, 车头照片={}, 车尾照片={}",
delivery.getLicensePlate(), delivery.getCarFrontPhoto(), delivery.getCarBehindPhoto());
}
}
} catch (Exception e) {
logger.error("从车辆表获取照片失败: " + e.getMessage(), e);
}
}
// 如果车辆表中没有照片,从司机信息中获取作为后备
if (!vehiclePhotoSet && carImg != null && !carImg.isEmpty()) {
// 按逗号分割car_img字段分别映射到车头和车尾照片
String[] carImgUrls = carImg.split(",");
@@ -244,14 +264,14 @@ public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> i
delivery.setCarFrontPhoto(singlePhoto);
delivery.setCarBehindPhoto(singlePhoto);
} else {
// 没有有效URL
delivery.setCarFrontPhoto("");
delivery.setCarBehindPhoto("");
// 没有有效URL设置为null
delivery.setCarFrontPhoto(null);
delivery.setCarBehindPhoto(null);
}
} else {
// 如果司机信息中没有照片,清空delivery表中的照片
delivery.setCarFrontPhoto("");
delivery.setCarBehindPhoto("");
} else if (!vehiclePhotoSet) {
// 如果车辆表和司机信息中没有照片,设置为null
delivery.setCarFrontPhoto(null);
delivery.setCarBehindPhoto(null);
}
}
} catch (Exception e) {
@@ -522,12 +542,14 @@ public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> i
delivery.setEndLocation(dto.getEndLocation());
delivery.setEndLon(dto.getEndLon());
delivery.setEndLat(dto.getEndLat());
// 预计到达
// 预计出发时间
delivery.setEstimatedDepartureTime(dto.getEstimatedDepartureTime());
// 预计到达时间
delivery.setEstimatedDeliveryTime(dto.getEstimatedArrivalTime());
// 过磅重量
delivery.setEmptyWeight(dto.getEmptyWeight());
delivery.setEntruckWeight(dto.getEntruckWeight());
delivery.setLandingEntruckWeight(dto.getLandingEntruckWeight());
// 过磅重量将空字符串转换为null避免数据库DECIMAL字段类型错误
delivery.setEmptyWeight(StringUtils.isNotEmpty(dto.getEmptyWeight()) ? dto.getEmptyWeight() : null);
delivery.setEntruckWeight(StringUtils.isNotEmpty(dto.getEntruckWeight()) ? dto.getEntruckWeight() : null);
delivery.setLandingEntruckWeight(StringUtils.isNotEmpty(dto.getLandingEntruckWeight()) ? dto.getLandingEntruckWeight() : null);
// 照片
delivery.setQuarantineTickeyUrl(dto.getQuarantineTickeyUrl());
delivery.setPoundListImg(dto.getPoundListImg());
@@ -551,10 +573,13 @@ public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> i
try {
Vehicle vehicle = vehicleMapper.selectByLicensePlate(dto.getPlateNumber());
if (vehicle != null) {
delivery.setCarFrontPhoto(vehicle.getCarFrontPhoto());
delivery.setCarBehindPhoto(vehicle.getCarRearPhoto());
// 将空字符串转换为null避免前端显示问题
String carFrontPhoto = vehicle.getCarFrontPhoto();
String carRearPhoto = vehicle.getCarRearPhoto();
delivery.setCarFrontPhoto(StringUtils.isNotEmpty(carFrontPhoto) ? carFrontPhoto : null);
delivery.setCarBehindPhoto(StringUtils.isNotEmpty(carRearPhoto) ? carRearPhoto : null);
logger.info("设置车辆照片: 车头照片={}, 车尾照片={}",
vehicle.getCarFrontPhoto(), vehicle.getCarRearPhoto());
delivery.getCarFrontPhoto(), delivery.getCarBehindPhoto());
}
} catch (Exception e) {
}
@@ -691,6 +716,14 @@ public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> i
delivery.setEndLon(dto.getEndLon());
}
// 更新时间字段
if (dto.getEstimatedDepartureTime() != null) {
delivery.setEstimatedDepartureTime(dto.getEstimatedDepartureTime());
}
if (dto.getEstimatedArrivalTime() != null) {
delivery.setEstimatedDeliveryTime(dto.getEstimatedArrivalTime());
}
// 更新其他业务字段
if (dto.getSupplierId() != null) {
delivery.setSupplierId(dto.getSupplierId());
@@ -717,6 +750,29 @@ public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> i
delivery.setFirmPrice(dto.getFirmPrice());
}
// 根据车牌号从车辆表重新获取车辆照片(编辑时同步更新照片)
// 这样即使车辆表中的照片有更新,也能同步到运送清单
if (delivery.getLicensePlate() != null && StringUtils.isNotEmpty(delivery.getLicensePlate())) {
try {
Vehicle vehicle = vehicleMapper.selectByLicensePlate(delivery.getLicensePlate());
if (vehicle != null) {
// 将空字符串转换为null避免前端显示问题
String carFrontPhoto = vehicle.getCarFrontPhoto();
String carRearPhoto = vehicle.getCarRearPhoto();
delivery.setCarFrontPhoto(StringUtils.isNotEmpty(carFrontPhoto) ? carFrontPhoto : null);
delivery.setCarBehindPhoto(StringUtils.isNotEmpty(carRearPhoto) ? carRearPhoto : null);
logger.info("更新车辆照片: 车牌号={}, 车头照片={}, 车尾照片={}",
delivery.getLicensePlate(), delivery.getCarFrontPhoto(), delivery.getCarBehindPhoto());
} else {
// 如果车辆表中没有该车牌号的记录,清空照片
delivery.setCarFrontPhoto(null);
delivery.setCarBehindPhoto(null);
}
} catch (Exception e) {
logger.error("从车辆表获取照片失败: " + e.getMessage(), e);
}
}
// 保存更新
boolean updated = this.updateById(delivery);
if (updated) {
@@ -920,14 +976,14 @@ public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> i
deliveryLogVo.setCarFrontPhoto(singlePhoto);
deliveryLogVo.setCarBehindPhoto(singlePhoto);
} else {
// 没有有效URL
deliveryLogVo.setCarFrontPhoto("");
deliveryLogVo.setCarBehindPhoto("");
// 没有有效URL设置为null
deliveryLogVo.setCarFrontPhoto(null);
deliveryLogVo.setCarBehindPhoto(null);
}
} else {
// 如果司机信息中没有照片,清空delivery表中的照片
deliveryLogVo.setCarFrontPhoto("");
deliveryLogVo.setCarBehindPhoto("");
// 如果司机信息中没有照片,设置为null
deliveryLogVo.setCarFrontPhoto(null);
deliveryLogVo.setCarBehindPhoto(null);
}
// 如果车身照片仍然为空,尝试根据司机姓名和车牌号查询其他相关记录
@@ -1348,8 +1404,30 @@ public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> i
// 注意:车牌号不从司机表获取,车牌号是独立的模块
delivery.setDriverMobile(driverMobile);
// 强制从司机信息中获取最新的车身照片,确保数据一致性
if (carImg != null && !carImg.isEmpty()) {
// 优先从车辆表获取车身照片(根据车牌号)
// 如果车辆表中没有,再从司机信息中获取作为后备
boolean vehiclePhotoSet = false;
if (delivery.getLicensePlate() != null && StringUtils.isNotEmpty(delivery.getLicensePlate())) {
try {
Vehicle vehicle = vehicleMapper.selectByLicensePlate(delivery.getLicensePlate());
if (vehicle != null) {
String carFrontPhoto = vehicle.getCarFrontPhoto();
String carRearPhoto = vehicle.getCarRearPhoto();
if (StringUtils.isNotEmpty(carFrontPhoto) || StringUtils.isNotEmpty(carRearPhoto)) {
delivery.setCarFrontPhoto(StringUtils.isNotEmpty(carFrontPhoto) ? carFrontPhoto : null);
delivery.setCarBehindPhoto(StringUtils.isNotEmpty(carRearPhoto) ? carRearPhoto : null);
vehiclePhotoSet = true;
logger.debug("从车辆表获取照片: 车牌号={}, 车头照片={}, 车尾照片={}",
delivery.getLicensePlate(), delivery.getCarFrontPhoto(), delivery.getCarBehindPhoto());
}
}
} catch (Exception e) {
logger.error("从车辆表获取照片失败: " + e.getMessage(), e);
}
}
// 如果车辆表中没有照片,从司机信息中获取作为后备
if (!vehiclePhotoSet && carImg != null && !carImg.isEmpty()) {
// 按逗号分割car_img字段分别映射到车头和车尾照片
String[] carImgUrls = carImg.split(",");
@@ -1367,14 +1445,14 @@ public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> i
delivery.setCarFrontPhoto(singlePhoto);
delivery.setCarBehindPhoto(singlePhoto);
} else {
// 没有有效URL
delivery.setCarFrontPhoto("");
delivery.setCarBehindPhoto("");
// 没有有效URL设置为null
delivery.setCarFrontPhoto(null);
delivery.setCarBehindPhoto(null);
}
} else {
// 如果司机信息中没有照片,清空delivery表中的照片
delivery.setCarFrontPhoto("");
delivery.setCarBehindPhoto("");
} else if (!vehiclePhotoSet) {
// 如果车辆表和司机信息中没有照片,设置为null
delivery.setCarFrontPhoto(null);
delivery.setCarBehindPhoto(null);
}
// 已废弃:不再根据司机姓名和车牌号查询相关记录

View File

@@ -11,6 +11,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -75,13 +77,48 @@ public class VehicleServiceImpl extends ServiceImpl<VehicleMapper, Vehicle> impl
vehicle.setCreatedBy(userId);
vehicle.setCreateTime(new Date());
// 插入数据库
int result = vehicleMapper.insert(vehicle);
try {
// 插入数据库
int result = vehicleMapper.insert(vehicle);
if (result > 0) {
return AjaxResult.success("新增车辆成功");
} else {
return AjaxResult.error("新增车辆失败");
if (result > 0) {
return AjaxResult.success("新增车辆成功");
} else {
return AjaxResult.error("新增车辆失败");
}
} catch (DuplicateKeyException e) {
// 捕获重复键异常(车牌号重复)
String errorMessage = e.getMessage();
if (errorMessage != null && errorMessage.contains("license_plate")) {
return AjaxResult.error("车牌号已存在,请使用其他车牌号");
}
return AjaxResult.error("数据重复:" + errorMessage);
} catch (DataIntegrityViolationException e) {
// 捕获数据库约束异常,提供更友好的错误信息
String errorMessage = e.getMessage();
// 记录完整错误信息以便调试
e.printStackTrace();
if (errorMessage != null && errorMessage.contains("record_code") && errorMessage.contains("too long")) {
return AjaxResult.error("牧运通备案码图片URL过长请重新上传或联系管理员调整数据库字段长度。如果已修改数据库字段为TEXT类型请重启应用或清空连接池缓存");
} else if (errorMessage != null && errorMessage.contains("Data too long")) {
return AjaxResult.error("上传的数据内容过长请检查图片URL或联系管理员");
} else if (errorMessage != null && errorMessage.contains("license_plate")) {
return AjaxResult.error("车牌号已存在,请使用其他车牌号");
}
// 返回完整错误信息以便调试
return AjaxResult.error("新增车辆失败:" + errorMessage);
} catch (Exception e) {
// 捕获其他可能的异常
String errorMessage = e.getMessage();
// 记录完整错误信息以便调试
e.printStackTrace();
if (errorMessage != null && errorMessage.contains("record_code") && errorMessage.contains("too long")) {
return AjaxResult.error("牧运通备案码图片URL过长请重新上传或联系管理员调整数据库字段长度。如果已修改数据库字段为TEXT类型请重启应用或清空连接池缓存");
} else if (errorMessage != null && errorMessage.contains("license_plate") && errorMessage.contains("Duplicate")) {
return AjaxResult.error("车牌号已存在,请使用其他车牌号");
}
// 返回完整错误信息以便调试
return AjaxResult.error("新增车辆失败:" + errorMessage);
}
}
@@ -106,13 +143,48 @@ public class VehicleServiceImpl extends ServiceImpl<VehicleMapper, Vehicle> impl
vehicle.setUpdatedBy(userId);
vehicle.setUpdateTime(new Date());
// 更新数据库
int result = vehicleMapper.updateById(vehicle);
try {
// 更新数据库
int result = vehicleMapper.updateById(vehicle);
if (result > 0) {
return AjaxResult.success("更新车辆成功");
} else {
return AjaxResult.error("更新车辆失败");
if (result > 0) {
return AjaxResult.success("更新车辆成功");
} else {
return AjaxResult.error("更新车辆失败");
}
} catch (DuplicateKeyException e) {
// 捕获重复键异常(车牌号重复)
String errorMessage = e.getMessage();
if (errorMessage != null && errorMessage.contains("license_plate")) {
return AjaxResult.error("车牌号已存在,请使用其他车牌号");
}
return AjaxResult.error("数据重复:" + errorMessage);
} catch (DataIntegrityViolationException e) {
// 捕获数据库约束异常,提供更友好的错误信息
String errorMessage = e.getMessage();
// 记录完整错误信息以便调试
e.printStackTrace();
if (errorMessage != null && errorMessage.contains("record_code") && errorMessage.contains("too long")) {
return AjaxResult.error("牧运通备案码图片URL过长请重新上传或联系管理员调整数据库字段长度。如果已修改数据库字段为TEXT类型请重启应用或清空连接池缓存");
} else if (errorMessage != null && errorMessage.contains("Data too long")) {
return AjaxResult.error("上传的数据内容过长请检查图片URL或联系管理员");
} else if (errorMessage != null && errorMessage.contains("license_plate")) {
return AjaxResult.error("车牌号已存在,请使用其他车牌号");
}
// 返回完整错误信息以便调试
return AjaxResult.error("更新车辆失败:" + errorMessage);
} catch (Exception e) {
// 捕获其他可能的异常
String errorMessage = e.getMessage();
// 记录完整错误信息以便调试
e.printStackTrace();
if (errorMessage != null && errorMessage.contains("record_code") && errorMessage.contains("too long")) {
return AjaxResult.error("牧运通备案码图片URL过长请重新上传或联系管理员调整数据库字段长度。如果已修改数据库字段为TEXT类型请重启应用或清空连接池缓存");
} else if (errorMessage != null && errorMessage.contains("license_plate") && errorMessage.contains("Duplicate")) {
return AjaxResult.error("车牌号已存在,请使用其他车牌号");
}
// 返回完整错误信息以便调试
return AjaxResult.error("更新车辆失败:" + errorMessage);
}
}

View File

@@ -0,0 +1,14 @@
-- 扩展耳标与项圈日志表的经纬度字段长度,避免坐标精度过高导致超长
USE cattletrade;
-- jbq_client_log智能耳标日志表
ALTER TABLE jbq_client_log
MODIFY COLUMN latitude VARCHAR(32) COMMENT '纬度',
MODIFY COLUMN longitude VARCHAR(32) COMMENT '经度';
-- xq_client_log项圈日志表
ALTER TABLE xq_client_log
MODIFY COLUMN latitude VARCHAR(32) COMMENT '纬度',
MODIFY COLUMN longitude VARCHAR(32) COMMENT '经度';

View File

@@ -0,0 +1,16 @@
-- 为 delivery 表添加 estimated_departure_time 字段(预计出发时间)
-- 此脚本已手动执行,保留作为参考文档
USE cattletrade;
-- 添加预计出发时间字段(如果字段已存在,此语句会报错,可以忽略)
-- ALTER TABLE delivery
-- ADD COLUMN estimated_departure_time DATETIME COMMENT '预计出发时间'
-- AFTER estimated_delivery_time;
-- 为现有记录设置默认值(使用创建时间作为默认的预计出发时间)
-- 如果字段中已有部分数据,可以执行此更新语句为 NULL 值设置默认值
UPDATE delivery
SET estimated_departure_time = create_time
WHERE estimated_departure_time IS NULL;

View File

@@ -0,0 +1,18 @@
-- 修复 vehicle 表 record_code 字段长度问题
-- 将 record_code 字段从当前长度扩展为 VARCHAR(1000) 以支持较长的图片URL
-- 同时扩展其他图片URL字段以确保一致性
-- 修改 record_code 字段
ALTER TABLE vehicle MODIFY COLUMN record_code VARCHAR(1000) COMMENT '牧运通备案码图片URL';
-- 修改其他图片URL字段如果需要建议也一起修改
ALTER TABLE vehicle MODIFY COLUMN car_front_photo VARCHAR(1000) COMMENT '车头照片URL';
ALTER TABLE vehicle MODIFY COLUMN car_rear_photo VARCHAR(1000) COMMENT '车尾照片URL';
ALTER TABLE vehicle MODIFY COLUMN driving_license_photo VARCHAR(1000) COMMENT '行驶证照片URL';
-- 如果您的数据库不支持修改字段长度,或者需要更大的容量,可以使用 TEXT 类型:
-- ALTER TABLE vehicle MODIFY COLUMN record_code TEXT COMMENT '牧运通备案码图片URL';
-- ALTER TABLE vehicle MODIFY COLUMN car_front_photo TEXT COMMENT '车头照片URL';
-- ALTER TABLE vehicle MODIFY COLUMN car_rear_photo TEXT COMMENT '车尾照片URL';
-- ALTER TABLE vehicle MODIFY COLUMN driving_license_photo TEXT COMMENT '行驶证照片URL';