Files
stand_acs/acs2/nladmin-system/DEVELOPMENT_GUIDE.md
2026-04-16 14:01:59 +08:00

538 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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. 检查权限配置是否正确
---