# 部门分公司ID获取方法说明
## 概述
新增了独立的方法 `selectBranchCompanyIdByDeptId`,用于获取指定部门ID对应的分公司ID(parent_id=100的部门)。
## 方法定义
### Mapper接口
**文件**: `SysDeptMapper.java`
```java
/**
* 获取指定部门ID的分公司ID(parent_id=100的部门)
* 如果传入的就是分公司,直接返回;否则从ancestors中查找分公司ID
*
* @param deptId 部门ID
* @return 分公司ID,如果找不到则返回null
*/
public Long selectBranchCompanyIdByDeptId(@Param("deptId") Long deptId);
```
### SQL实现
**文件**: `SysDeptMapper.xml`
```xml
```
## 使用示例
### 在Service层中使用
```java
@Autowired
private SysDeptMapper deptMapper;
public void someMethod(Long deptId) {
// 获取分公司ID
Long branchCompanyId = deptMapper.selectBranchCompanyIdByDeptId(deptId);
if (branchCompanyId != null) {
// 使用分公司ID进行后续操作
System.out.println("分公司ID: " + branchCompanyId);
} else {
// 找不到分公司(可能是总公司或数据异常)
System.out.println("未找到分公司ID");
}
}
```
### 在MyBatis XML中使用
可以在其他Mapper的SQL中作为子查询使用:
```xml
```
## 工作原理
### 部门结构示例
```
总公司 (dept_id=100, parent_id=0, ancestors="0")
├── 北京分公司 (dept_id=101, parent_id=100, ancestors="0,100")
│ ├── 技术部 (dept_id=201, parent_id=101, ancestors="0,100,101")
│ └── 业务部 (dept_id=202, parent_id=101, ancestors="0,100,101")
└── 上海分公司 (dept_id=102, parent_id=100, ancestors="0,100")
└── 市场部 (dept_id=203, parent_id=102, ancestors="0,100,102")
```
### 查询逻辑
1. **传入分公司ID** (如: deptId=101)
- 检查 `parent_id = 100` ✅
- 直接返回: `101`
2. **传入子部门ID** (如: deptId=201)
- 检查 `parent_id = 100` ❌
- 查询 `ancestors = "0,100,101"`
- 使用 `FIND_IN_SET` 查找 `parent_id=100` 的部门
- 找到匹配: `101`
- 返回: `101`
3. **传入总公司ID** (如: deptId=100)
- 检查 `parent_id = 100` ❌ (parent_id=0)
- ancestors中没有parent_id=100的部门
- 返回: `null`
## 应用场景
### 1. 车辆查询
用户在任意部门,查询时自动定位到所属分公司的车辆:
```java
// 原始实现(VehicleInfoMapper.xml)
Long branchCompanyId = deptMapper.selectBranchCompanyIdByDeptId(userDeptId);
List vehicles = vehicleMapper.selectByDeptId(branchCompanyId);
```
### 2. 数据权限过滤
限制用户只能查看所属分公司的数据:
```java
public List getDataList(Long userDeptId) {
Long branchCompanyId = deptMapper.selectBranchCompanyIdByDeptId(userDeptId);
return someMapper.selectByBranchCompany(branchCompanyId);
}
```
### 3. 报表统计
按分公司维度统计数据:
```java
public Map getStatistics(Long deptId) {
Long branchCompanyId = deptMapper.selectBranchCompanyIdByDeptId(deptId);
return statisticsService.getByBranchCompany(branchCompanyId);
}
```
## 性能优化建议
### 1. 添加索引
确保以下字段有索引:
```sql
-- 已有的索引
CREATE INDEX idx_parent_id ON sys_dept(parent_id);
CREATE INDEX idx_del_flag ON sys_dept(del_flag);
-- 建议添加复合索引
CREATE INDEX idx_parent_del ON sys_dept(parent_id, del_flag);
```
### 2. 结果缓存
对于频繁查询的场景,可以考虑缓存结果:
```java
@Cacheable(value = "branchCompany", key = "#deptId")
public Long getBranchCompanyId(Long deptId) {
return deptMapper.selectBranchCompanyIdByDeptId(deptId);
}
```
## 注意事项
1. **返回值可能为null**
- 总公司(dept_id=100)查询时会返回null
- 部门数据异常时也会返回null
- 使用时需要做空值判断
2. **只查询正常部门**
- SQL中已过滤 `del_flag = '0'`
- 被删除的部门不会被查询到
3. **分公司定义**
- 分公司必须满足 `parent_id = 100`
- 如果组织架构调整,需要确保这个规则仍然适用
4. **ancestors字段维护**
- 部门层级变更时必须更新ancestors字段
- ancestors格式必须是逗号分隔的ID列表
## 测试场景
### 测试用例1: 传入分公司ID
```
输入: deptId = 101 (北京分公司)
预期输出: 101
```
### 测试用例2: 传入子部门ID
```
输入: deptId = 201 (技术部)
预期输出: 101 (北京分公司)
```
### 测试用例3: 传入总公司ID
```
输入: deptId = 100 (总公司)
预期输出: null
```
### 测试用例4: 传入多级子部门ID
```
输入: deptId = 301 (假设技术部下的小组,ancestors="0,100,101,201")
预期输出: 101 (北京分公司)
```
## 更新日志
- **2025-01-25**: 创建独立方法 `selectBranchCompanyIdByDeptId`
- 目的: 简化分公司ID查询逻辑,提高代码复用性