opt:md文件优化
This commit is contained in:
537
acs2/nladmin-system/DEVELOPMENT_GUIDE.md
Normal file
537
acs2/nladmin-system/DEVELOPMENT_GUIDE.md
Normal file
@@ -0,0 +1,537 @@
|
||||
# NL Admin System 开发手册
|
||||
|
||||
## 1. 开发环境搭建
|
||||
|
||||
### 1.1 环境要求
|
||||
|
||||
| 软件 | 版本 | 说明 |
|
||||
| :--- | :--- | :--- |
|
||||
| JDK | 1.8 | 必须使用 Java 8 |
|
||||
| Maven | 3.6+ | 依赖管理工具 |
|
||||
| MySQL | 5.7+ | 主数据库 |
|
||||
| Redis | 3.2+ | 缓存与会话管理 |
|
||||
|
||||
### 1.2 JDK 配置
|
||||
|
||||
```bash
|
||||
# 设置环境变量
|
||||
export JAVA_HOME=/path/to/jdk1.8
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
```
|
||||
|
||||
### 1.3 Maven 配置
|
||||
|
||||
`settings.xml` :
|
||||
|
||||
```xml
|
||||
<mirror>
|
||||
<id>nexus-aliyun</id>
|
||||
<mirrorOf>central</mirrorOf>
|
||||
<name>Nexus aliyun</name>
|
||||
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
|
||||
</mirror>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 项目结构详解
|
||||
|
||||
### 2.1 模块划分
|
||||
|
||||
```
|
||||
src/main/java/org/nl/
|
||||
├── AppRun.java # Spring Boot 启动类
|
||||
├── acs/ # 设备控制模块(核心业务)
|
||||
│ ├── apiAdd/ # 地址管理
|
||||
│ ├── autoThread/ # 自动线程管理
|
||||
│ ├── device/ # 设备管理
|
||||
│ ├── iot/ # IoT数据处理
|
||||
│ ├── layout/ # 布局管理
|
||||
│ ├── log/ # 日志管理
|
||||
│ └── task/ # 任务调度
|
||||
├── common/ # 通用模块(工具、配置、异常等)
|
||||
│ ├── annotation/ # 自定义注解
|
||||
│ ├── base/ # 基础类(DTO、Mapper等)
|
||||
│ ├── db/ # 数据库工具
|
||||
│ ├── domain/ # 通用领域模型
|
||||
│ ├── enums/ # 枚举类
|
||||
│ ├── exception/ # 异常处理
|
||||
│ ├── logging/ # 日志切面
|
||||
│ ├── mnt/ # 监控与维护
|
||||
│ ├── security/ # 安全配置
|
||||
│ └── utils/ # 工具类
|
||||
├── config/ # 配置类
|
||||
│ ├── jackson/ # JSON序列化配置
|
||||
│ ├── language/ # 国际化配置
|
||||
│ ├── lucene/ # 全文搜索配置
|
||||
│ ├── mybatis/ # MyBatis配置
|
||||
│ ├── redis/ # Redis配置
|
||||
│ ├── saconfig/ # Sa-Token配置
|
||||
│ └── thread/ # 线程池配置
|
||||
├── extInterface/ # 外部接口
|
||||
│ ├── agvKit/ # AGV系统对接
|
||||
│ └── wms/ # WMS系统对接
|
||||
└── system/ # 系统管理
|
||||
└── controller/ # 系统控制器
|
||||
```
|
||||
|
||||
### 2.2 核心模块说明
|
||||
|
||||
| 模块 | 职责 | 说明 |
|
||||
| :--- | :--- | :--- |
|
||||
| `acs/` | 设备控制核心 | 包含设备管理、任务调度、IoT通信等核心业务 |
|
||||
| `common/` | 通用工具 | 提供基础工具类、异常处理、日志等通用能力 |
|
||||
| `config/` | 配置管理 | Spring配置类、第三方组件配置 |
|
||||
| `extInterface/` | 外部对接 | AGV、WMS等外部系统接口 |
|
||||
| `system/` | 系统管理 | 用户、角色、权限等系统管理功能 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 代码规范
|
||||
|
||||
### 3.1 命名规范
|
||||
|
||||
| 类型 | 规范 | 示例 |
|
||||
| :--- | :--- | :--- |
|
||||
| 包名 | 全小写,使用点分隔 | `org.nl.acs.device` |
|
||||
| 类名 | 大驼峰命名法 | `DeviceController` |
|
||||
| 方法名 | 小驼峰命名法 | `getDeviceById` |
|
||||
| 变量名 | 小驼峰命名法 | `deviceName` |
|
||||
| 常量名 | 全大写,下划线分隔 | `MAX_PAGE_SIZE` |
|
||||
| 接口名 | 大驼峰,以 `I` 开头 | `IDeviceService` |
|
||||
|
||||
### 3.2 格式规范
|
||||
|
||||
- 使用 4 个空格缩进(禁止使用 Tab)
|
||||
- 每行代码不超过 120 字符
|
||||
- 方法之间空一行
|
||||
- 类成员变量与方法之间空两行
|
||||
|
||||
### 3.3 注释规范
|
||||
|
||||
```java
|
||||
/**
|
||||
* 获取设备详情
|
||||
* @param id 设备ID
|
||||
* @return 设备信息
|
||||
*/
|
||||
public DeviceDto getDeviceById(Long id) {
|
||||
// 业务逻辑
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 异常处理规范
|
||||
|
||||
```java
|
||||
// 错误示例
|
||||
try {
|
||||
// 业务逻辑
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(); // 禁止直接打印堆栈
|
||||
}
|
||||
|
||||
// 正确示例
|
||||
try {
|
||||
// 业务逻辑
|
||||
} catch (Exception e) {
|
||||
log.error("获取设备失败, id: {}", id, e);
|
||||
throw new BadRequestException("获取设备失败");
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 开发流程
|
||||
|
||||
### 4.1 需求分析
|
||||
|
||||
1. 明确需求范围和业务场景
|
||||
2. 分析与现有模块的依赖关系
|
||||
3. 设计数据模型和接口
|
||||
|
||||
### 4.2 编码流程
|
||||
|
||||
```
|
||||
需求分析 → 设计文档 → 创建DTO → 创建Entity → 创建Mapper → 创建Service → 创建Controller → 单元测试
|
||||
```
|
||||
|
||||
### 4.3 Git 工作流
|
||||
|
||||
```bash
|
||||
# 1. 从主分支拉取最新代码
|
||||
git checkout develop
|
||||
git pull origin develop
|
||||
|
||||
# 2. 创建特性分支
|
||||
git checkout -b feature/xxx-feature
|
||||
|
||||
# 3. 开发并提交
|
||||
git add .
|
||||
git commit -m "feat: 实现xxx功能"
|
||||
|
||||
# 4. 推送到远程
|
||||
git push origin feature/xxx-feature
|
||||
|
||||
# 5. 创建 Pull Request
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 数据库设计规范
|
||||
|
||||
### 5.1 命名规范
|
||||
|
||||
| 对象 | 规范 | 示例 |
|
||||
| :--- | :--- | :--- |
|
||||
| 表名 | 小写,下划线分隔,前缀 `sys_` | `sys_device` |
|
||||
| 字段名 | 小写,下划线分隔 | `device_name` |
|
||||
| 主键 | 统一命名为 `id`,自增 | `id BIGINT PRIMARY KEY AUTO_INCREMENT` |
|
||||
|
||||
### 5.2 字段类型选择
|
||||
|
||||
| 类型 | 用途 | 示例 |
|
||||
| :--- | :--- | :--- |
|
||||
| BIGINT | 主键、ID字段 | `id`, `user_id` |
|
||||
| VARCHAR | 字符串,最大255 | `name`, `code` |
|
||||
| TEXT | 长文本 | `description` |
|
||||
| DATETIME | 日期时间 | `create_time`, `update_time` |
|
||||
| INT | 整数 | `status`, `sort` |
|
||||
| DECIMAL | 精确小数 | `price`, `quantity` |
|
||||
|
||||
### 5.3 通用字段
|
||||
|
||||
```sql
|
||||
CREATE TABLE example (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
|
||||
create_by VARCHAR(64) COMMENT '创建人',
|
||||
create_time DATETIME COMMENT '创建时间',
|
||||
update_by VARCHAR(64) COMMENT '更新人',
|
||||
update_time DATETIME COMMENT '更新时间',
|
||||
is_deleted TINYINT DEFAULT 0 COMMENT '删除标记(0-未删除,1-已删除)',
|
||||
remark VARCHAR(255) COMMENT '备注'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='示例表';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. API 开发规范
|
||||
|
||||
### 6.1 RESTful 风格
|
||||
|
||||
| 操作 | HTTP方法 | 路径 |
|
||||
| :--- | :--- | :--- |
|
||||
| 查询列表 | GET | `/api/device` |
|
||||
| 查询单个 | GET | `/api/device/{id}` |
|
||||
| 新增 | POST | `/api/device` |
|
||||
| 更新 | PUT | `/api/device/{id}` |
|
||||
| 删除 | DELETE | `/api/device/{id}` |
|
||||
|
||||
### 6.2 统一响应格式
|
||||
|
||||
```java
|
||||
// 成功响应
|
||||
{
|
||||
"code": 200,
|
||||
"message": "操作成功",
|
||||
"data": {...},
|
||||
"timestamp": 1620000000000
|
||||
}
|
||||
|
||||
// 失败响应
|
||||
{
|
||||
"code": 400,
|
||||
"message": "参数错误",
|
||||
"data": null,
|
||||
"timestamp": 1620000000000
|
||||
}
|
||||
```
|
||||
|
||||
### 6.3 Controller 示例
|
||||
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/api/device")
|
||||
public class DeviceController {
|
||||
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<Object> getAll(DeviceQuery query) {
|
||||
List<DeviceDto> devices = deviceService.queryAll(query);
|
||||
return ResponseEntity.ok(devices);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<Object> getById(@PathVariable Long id) {
|
||||
DeviceDto device = deviceService.getById(id);
|
||||
return ResponseEntity.ok(device);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<Object> create(@RequestBody DeviceDto dto) {
|
||||
deviceService.create(dto);
|
||||
return ResponseEntity.ok("创建成功");
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<Object> update(@PathVariable Long id, @RequestBody DeviceDto dto) {
|
||||
deviceService.update(id, dto);
|
||||
return ResponseEntity.ok("更新成功");
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<Object> delete(@PathVariable Long id) {
|
||||
deviceService.delete(id);
|
||||
return ResponseEntity.ok("删除成功");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Service 层开发规范
|
||||
|
||||
### 7.1 接口定义
|
||||
|
||||
```java
|
||||
public interface IDeviceService {
|
||||
|
||||
/**
|
||||
* 查询设备列表
|
||||
*/
|
||||
List<DeviceDto> queryAll(DeviceQuery query);
|
||||
|
||||
/**
|
||||
* 根据ID查询设备
|
||||
*/
|
||||
DeviceDto getById(Long id);
|
||||
|
||||
/**
|
||||
* 创建设备
|
||||
*/
|
||||
void create(DeviceDto dto);
|
||||
|
||||
/**
|
||||
* 更新设备
|
||||
*/
|
||||
void update(Long id, DeviceDto dto);
|
||||
|
||||
/**
|
||||
* 删除设备
|
||||
*/
|
||||
void delete(Long id);
|
||||
}
|
||||
```
|
||||
|
||||
### 7.2 实现类规范
|
||||
|
||||
```java
|
||||
@Service
|
||||
public class DeviceServiceImpl implements IDeviceService {
|
||||
|
||||
@Autowired
|
||||
private DeviceMapper deviceMapper;
|
||||
|
||||
@Autowired
|
||||
private RedisUtils redisUtils;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void create(DeviceDto dto) {
|
||||
// 参数校验
|
||||
if (StrUtil.isEmpty(dto.getName())) {
|
||||
throw new BadRequestException("设备名称不能为空");
|
||||
}
|
||||
|
||||
// 转换为实体
|
||||
Device entity = ConvertUtil.convert(dto, Device.class);
|
||||
|
||||
// 保存到数据库
|
||||
deviceMapper.insert(entity);
|
||||
|
||||
// 更新缓存
|
||||
redisUtils.set("device:" + entity.getId(), entity);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 安全规范
|
||||
|
||||
### 8.1 权限控制
|
||||
|
||||
使用 Sa-Token 进行权限控制:
|
||||
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/api/admin")
|
||||
public class AdminController {
|
||||
|
||||
@GetMapping("/users")
|
||||
public ResponseEntity<Object> getUsers() {
|
||||
return ResponseEntity.ok(userService.getAll());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8.2 参数校验
|
||||
|
||||
使用 `@Valid` 注解进行参数校验:
|
||||
|
||||
```java
|
||||
public class DeviceDto {
|
||||
|
||||
@NotBlank(message = "设备名称不能为空")
|
||||
@Size(max = 100, message = "设备名称不能超过100字符")
|
||||
private String name;
|
||||
|
||||
@Min(value = 0, message = "状态值不能为负数")
|
||||
private Integer status;
|
||||
}
|
||||
```
|
||||
|
||||
### 8.3 SQL 注入防护
|
||||
|
||||
```java
|
||||
// 正确:使用参数化查询
|
||||
QueryWrapper<Device> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("device_code", deviceCode);
|
||||
deviceMapper.selectOne(wrapper);
|
||||
|
||||
// 错误:拼接SQL
|
||||
String sql = "SELECT * FROM device WHERE code = '" + deviceCode + "'";
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 日志规范
|
||||
|
||||
### 9.1 日志级别
|
||||
|
||||
| 级别 | 用途 |
|
||||
| :--- | :--- |
|
||||
| DEBUG | 详细的调试信息,生产环境关闭 |
|
||||
| INFO | 重要的业务流程日志 |
|
||||
| WARN | 警告信息,需要关注但不影响运行 |
|
||||
| ERROR | 错误信息,需要立即处理 |
|
||||
|
||||
### 9.2 日志格式
|
||||
|
||||
```java
|
||||
// 错误示例
|
||||
log.info("设备ID: " + id + ", 名称: " + name);
|
||||
|
||||
// 正确示例
|
||||
log.info("创建设备成功, id: {}, name: {}", id, name);
|
||||
log.error("创建设备失败, id: {}, error: {}", id, e.getMessage(), e);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 测试规范
|
||||
|
||||
### 10.1 单元测试
|
||||
|
||||
```java
|
||||
@SpringBootTest
|
||||
class DeviceServiceTest {
|
||||
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@Test
|
||||
void testCreate() {
|
||||
DeviceDto dto = new DeviceDto();
|
||||
dto.setName("测试设备");
|
||||
dto.setCode("TEST001");
|
||||
|
||||
deviceService.create(dto);
|
||||
|
||||
DeviceDto result = deviceService.getById(1L);
|
||||
assertEquals("测试设备", result.getName());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 10.2 测试覆盖率
|
||||
|
||||
- 核心业务逻辑覆盖率 ≥ 80%
|
||||
- 工具类覆盖率 ≥ 90%
|
||||
- 新增代码必须有对应的单元测试
|
||||
|
||||
---
|
||||
|
||||
## 11. 部署与发布
|
||||
|
||||
### 11.1 配置管理
|
||||
|
||||
```bash
|
||||
# 开发环境
|
||||
java -jar nlsso-server.jar --spring.profiles.active=dev
|
||||
|
||||
# 生产环境
|
||||
java -jar nlsso-server.jar --spring.profiles.active=prod
|
||||
```
|
||||
|
||||
### 11.2 启动脚本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
APP_NAME=nlsso-server
|
||||
APP_DIR=/opt/app
|
||||
|
||||
cd $APP_DIR
|
||||
|
||||
# 停止旧进程
|
||||
PID=$(ps -ef | grep $APP_NAME | grep -v grep | awk '{print $2}')
|
||||
if [ -n "$PID" ]; then
|
||||
kill -9 $PID
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
# 启动新进程
|
||||
nohup java -jar $APP_DIR/$APP_NAME.jar --spring.profiles.active=prod > /dev/null 2>&1 &
|
||||
|
||||
echo "服务已启动"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. 常见问题
|
||||
|
||||
### 12.1 依赖冲突
|
||||
|
||||
问题:启动时报 `NoSuchMethodError`
|
||||
|
||||
解决方案:检查 `pom.xml` 中的依赖版本,使用 `mvn dependency:tree` 分析依赖树,排除冲突的依赖。
|
||||
|
||||
### 12.2 数据库连接失败
|
||||
|
||||
问题:无法连接数据库
|
||||
|
||||
解决方案:
|
||||
1. 检查数据库服务是否启动
|
||||
2. 检查 `application.yml` 中的数据库配置
|
||||
3. 检查数据库用户名和密码
|
||||
|
||||
### 12.3 Redis 连接失败
|
||||
|
||||
问题:缓存操作失败
|
||||
|
||||
解决方案:
|
||||
1. 检查 Redis 服务是否启动
|
||||
2. 检查 Redis 配置(主机、端口、密码)
|
||||
3. 检查防火墙规则
|
||||
|
||||
### 12.4 权限不足
|
||||
|
||||
问题:访问接口时返回 403
|
||||
|
||||
解决方案:
|
||||
1. 检查用户是否登录
|
||||
2. 检查用户是否具有相应权限
|
||||
3. 检查权限配置是否正确
|
||||
|
||||
---
|
||||
Reference in New Issue
Block a user