fix(watch): 修复手表设备绑定时部门归属逻辑错误
- 修改异步导入服务中手表设备的部门归属逻辑,以用户部门为准而非设备原有部门 - 为部门统计数据服务添加详细的JavaDoc注释说明业务逻辑 - 优化部门统计数据显示逻辑,支持一级、二级、三级部门的正确展示 - 移除手表绑定时的单位限制校验,允许跨单位绑定 - 在设备绑定时根据员工信息更新手表的单位组织编码 - 修复上传工具类中tar/apk文件上传的日志描述 - 调整Shiro配置中文件下载路径的安全策略
This commit is contained in:
+3
-2
@@ -336,8 +336,9 @@ public class AsyncImportService {
|
||||
updatedWatchDevice.setBindDate(watchDevice.getBindDate()==null?new Date():watchDevice.getBindDate());
|
||||
updatedWatchDevice.setUpdateDate(new Date());
|
||||
updatedWatchDevice.setUpdateBy(sysUser.getId());
|
||||
updatedWatchDevice.setDeptId(device.getDeptId());
|
||||
updatedWatchDevice.setOrgCode(device.getOrgCode());
|
||||
// 这里修改成以用户的部门为准,更新手表的所属部门
|
||||
updatedWatchDevice.setDeptId(sysCache.getDepartIdByOrgCode(user.getOrgCode()));
|
||||
updatedWatchDevice.setOrgCode(user.getOrgCode());
|
||||
updateList.add(updatedWatchDevice);
|
||||
}
|
||||
info1.setHandleMsg(index + "/" + count);
|
||||
|
||||
+3
-1
@@ -440,7 +440,9 @@ public class WatchDeviceController extends JeecgController<WatchDevice, IWatchDe
|
||||
return Result.error("已存在执行中的导入任务,请稍后导入或点击【查看导入任务】查看任务导出进度!");
|
||||
}
|
||||
if (!StringUtils.hasLength(deptId) || "undefined".equals(deptId)) {
|
||||
throw new JeecgBootException("部门不能为空");
|
||||
// throw new JeecgBootException("部门不能为空");
|
||||
//可为空,空则算入新疆油田公司
|
||||
deptId = sysCache.getDepartIdByOrgCode("A01");
|
||||
}
|
||||
String sheetName = "设备导入";
|
||||
String fileName = sheetName + "_" + DateUtils.getDate("yyyyMMddHHmmss");
|
||||
|
||||
+101
-6
@@ -595,11 +595,32 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
filter.setOrgCodeLeaf("A99A99A99");
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询部门统计数据(分页)
|
||||
*
|
||||
* @param filter 查询过滤条件,包含部门编码、时间范围、分页参数等
|
||||
* @return 分页的部门统计数据列表
|
||||
*/
|
||||
@Override
|
||||
public IPage<DeptStatData> getDeptData(DepartStatsFilter filter) {
|
||||
return getDeptData(filter, true).pagedData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询部门统计数据的核心实现
|
||||
* <p>
|
||||
* 执行流程:
|
||||
* 1. 权限校验,补全过滤条件
|
||||
* 2. 查询各部门设备总数 Map 和绑定/佩戴数 Map
|
||||
* 3. 根据过滤条件确定最终需要展示的部门列表
|
||||
* 4. 查询各部门异常预警数量
|
||||
* 5. 按需分页,将部门列表转换为统计 DTO
|
||||
* </p>
|
||||
*
|
||||
* @param filter 查询过滤条件
|
||||
* @param paged 是否需要分页,true=分页查询,false=全量查询(用于导出等场景)
|
||||
* @return 包含统计数据和中间结果的传输对象
|
||||
*/
|
||||
private DepartStatTransfer getDeptData(DepartStatsFilter filter, boolean paged) {
|
||||
authCheck(filter);
|
||||
DepartStatTransfer transfer = new DepartStatTransfer()
|
||||
@@ -639,12 +660,29 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
return transfer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将单个部门实体转换为统计 DTO
|
||||
* <p>
|
||||
* orgCode 编码规则:3位一层,如 A01=一级,A01A01=二级,A01A01A01=三级
|
||||
* 区分三种视图:
|
||||
* - 一级部门(orgCode 长度为 3):展示自身信息,叶子名称置为 "-",取自身设备总数
|
||||
* - 二级部门(orgCode 长度为 6):同一级,展示自身信息,叶子名称置为 "-",取自身设备总数
|
||||
* - 三级部门(orgCode 长度为 9):展示所属上级名称 + 自身名称,绑定/佩戴数取自身数据
|
||||
* 当 allSecond=true(全量视图)时,绑定/佩戴数始终取各部门自身数据
|
||||
* </p>
|
||||
*
|
||||
* @param depart 部门实体
|
||||
* @param transfer 包含所有统计中间数据的传输对象
|
||||
* @return 填充完毕的部门统计 DTO
|
||||
*/
|
||||
private DeptStatData transferData(SysDepart depart, DepartStatTransfer transfer) {
|
||||
DeptStatData deptStatData = new DeptStatData();
|
||||
String orgCode = null != depart ? depart.getOrgCode() : null;
|
||||
boolean allSecond = StrUtil.isEmpty(transfer.filter().getOrgCode());
|
||||
boolean isFirst = StrUtil.isNotEmpty(orgCode) && orgCode.length() == 3;
|
||||
boolean isSecond = StrUtil.isNotEmpty(orgCode) && orgCode.length() == 6;
|
||||
if (isSecond) {
|
||||
if (isFirst || isSecond) {
|
||||
// 一级/二级部门行:展示自身信息,叶子名称占位
|
||||
deptStatData.setOrgCode(orgCode);
|
||||
deptStatData.setOrgCodeLeaf(orgCode);
|
||||
deptStatData.setOrgCodeName(depart.getDepartName());
|
||||
@@ -655,6 +693,7 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
.getDeviceCount()
|
||||
);
|
||||
} else {
|
||||
// 三级部门行:展示所属上级名称 + 自身名称
|
||||
deptStatData.setOrgCode(Optional.ofNullable(transfer.secondDepart()).map(SysDepart::getOrgCode).orElse(""));
|
||||
deptStatData.setOrgCodeLeaf(orgCode);
|
||||
deptStatData.setOrgCodeName(Optional.ofNullable(transfer.secondDepart()).map(SysDepart::getDepartName).orElse(""));
|
||||
@@ -662,7 +701,7 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
}
|
||||
fillWatchNums(
|
||||
deptStatData,
|
||||
(!allSecond && isSecond)
|
||||
(!allSecond && (isFirst || isSecond))
|
||||
?
|
||||
transfer.secondDepartBindAndWearNum()
|
||||
:
|
||||
@@ -670,7 +709,7 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
);
|
||||
fillWarningNums(
|
||||
deptStatData,
|
||||
(!allSecond && isSecond)
|
||||
(!allSecond && (isFirst || isSecond))
|
||||
?
|
||||
transfer.secondDepartAbnormalCount()
|
||||
:
|
||||
@@ -679,12 +718,30 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
return deptStatData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充手表绑定与佩戴相关数量
|
||||
* <p>
|
||||
* assignedDeviceNums = 已绑定设备数
|
||||
* assignedUserNums = 已佩戴人数
|
||||
* undistributedUserNums = 已绑定但未佩戴数(bindCount - wearCount)
|
||||
* </p>
|
||||
*/
|
||||
private void fillWatchNums(DeptStatData deptStatData, DepartDeviceNum departDeviceNum) {
|
||||
deptStatData.setAssignedDeviceNums(Optional.ofNullable(departDeviceNum.getBindCount()).orElse(0));
|
||||
deptStatData.setAssignedUserNums(Optional.ofNullable(departDeviceNum.getWearCount()).orElse(0));
|
||||
deptStatData.setUndistributedUserNums(deptStatData.getAssignedDeviceNums() - deptStatData.getAssignedUserNums());
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充各健康指标的预警数量
|
||||
* <p>
|
||||
* 从 abnormalCountMap 中按事件类型取值:
|
||||
* stress → 压力预警数
|
||||
* heart_rate → 心率预警数
|
||||
* spo2 → 血氧预警数
|
||||
* temperature_anomalies → 体温预警数
|
||||
* </p>
|
||||
*/
|
||||
private void fillWarningNums(DeptStatData deptStatData, Map<String, AbnormalCount> abnormalCountMap) {
|
||||
deptStatData.setStressNums(Optional.ofNullable(abnormalCountMap.get("stress")).map(AbnormalCount::getWarningCount).orElse(0));
|
||||
deptStatData.setHeartRateNums(Optional.ofNullable(abnormalCountMap.get("heart_rate")).map(AbnormalCount::getWarningCount).orElse(0));
|
||||
@@ -722,6 +779,10 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
return sysCache.getDepartByOrgCode(filter.getOrgCodeLeaf());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询各部门的设备总数 Map(orgCode → 设备数)
|
||||
* 当过滤条件指定了三级部门(orgCodeLeaf 不为空)时,设备总数无需展示,直接返回空 Map
|
||||
*/
|
||||
private Map<String, DepartDeviceNum> getDepartDeviceNumMap(DepartStatsFilter filter) {
|
||||
if (StrUtil.isNotEmpty(filter.getOrgCodeLeaf())) {
|
||||
return Collections.emptyMap();
|
||||
@@ -732,6 +793,9 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
.collect(Collectors.toMap(DepartDeviceNum::getOrgCode, Function.identity()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询各部门的设备绑定数与佩戴数 Map(orgCode → 绑定/佩戴数)
|
||||
*/
|
||||
private Map<String, DepartDeviceNum> getDepartBindAndWearNumMap(DepartStatsFilter filter) {
|
||||
return watchStatisticsMapper.deviceBindAndWearNums(filter)
|
||||
.stream()
|
||||
@@ -739,6 +803,10 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
.collect(Collectors.toMap(DepartDeviceNum::getOrgCode, Function.identity()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询各部门各事件类型的异常预警数量,结构为双层 Map:
|
||||
* orgCode → (eventType → AbnormalCount)
|
||||
*/
|
||||
private Map<String, Map<String, AbnormalCount>> getDepartAbnormalCountMap(DepartStatsFilter filter) {
|
||||
return watchStatisticsMapper.abnormalWarningCount(filter)
|
||||
.stream()
|
||||
@@ -746,6 +814,12 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
.collect(Collectors.groupingBy(AbnormalCount::getOrgCode, Collectors.toMap(AbnormalCount::getEventType, Function.identity())));
|
||||
}
|
||||
|
||||
/**
|
||||
* 汇总二级部门下所有三级部门的绑定/佩戴数,用于二级部门行的数据展示
|
||||
* <p>
|
||||
* 仅在"指定了二级部门但未指定三级部门"时有效,其他情况返回 null
|
||||
* </p>
|
||||
*/
|
||||
private DepartDeviceNum getSecondDepartBindAndWearNum(DepartStatsFilter filter,
|
||||
Map<String, DepartDeviceNum> departBindAndWearNumMap) {
|
||||
if (StrUtil.isNotEmpty(filter.getOrgCodeLeaf()) || StrUtil.isEmpty(filter.getOrgCode())) {
|
||||
@@ -764,6 +838,13 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
return n1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 汇总二级部门下所有三级部门的异常预警数,用于二级部门行的数据展示
|
||||
* <p>
|
||||
* 仅在"指定了二级部门但未指定三级部门"时有效,其他情况返回 null
|
||||
* 合并时按 eventType 累加 warningCount
|
||||
* </p>
|
||||
*/
|
||||
private Map<String, AbnormalCount> getSecondDepartAbnormalCount(DepartStatsFilter filter,
|
||||
Map<String, Map<String, AbnormalCount>> departAbnormalCountMap) {
|
||||
if (StrUtil.isNotEmpty(filter.getOrgCodeLeaf()) || StrUtil.isEmpty(filter.getOrgCode())) {
|
||||
@@ -778,6 +859,14 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
return n1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据过滤条件确定最终需要展示的部门列表,分三种情况:
|
||||
* <ul>
|
||||
* <li>指定三级部门(orgCodeLeaf 不为空):仅返回该三级部门(无绑定数据则返回空)</li>
|
||||
* <li>指定二级部门(orgCode 不为空):返回该部门本身 + 其下有绑定数据的子部门,按层级(orgCode 长度)升序后再按排序字段排序</li>
|
||||
* <li>全量(orgCode 为空):返回所有有设备数据的部门,同样按层级升序后再按排序字段排序,确保一级部门排在最前</li>
|
||||
* </ul>
|
||||
*/
|
||||
private List<SysDepart> getFinalDeparts(DepartStatsFilter filter,
|
||||
Map<String, DepartDeviceNum> departDeviceNumMap,
|
||||
Map<String, DepartDeviceNum> departBindAndWearNumMap) {
|
||||
@@ -804,7 +893,10 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
return departDeviceNumMap.keySet()
|
||||
.stream()
|
||||
.map(sysBaseAPI::getDepartIdsByOrgCodeNew)
|
||||
.sorted(this::departComparator)
|
||||
.sorted(
|
||||
Comparator.<SysDepart>comparingInt(sysDepart -> sysDepart.getOrgCode().length())
|
||||
.thenComparing(this::departComparator)
|
||||
)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -825,6 +917,9 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
return order1.compareTo(order2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对内存中的部门列表执行分页截取
|
||||
*/
|
||||
private List<SysDepart> getPagedDeparts(List<SysDepart> sysDeparts, DepartStatsFilter filter) {
|
||||
return getSubList(sysDeparts, filter.getPageNo(), filter.getPageSize());
|
||||
}
|
||||
@@ -2089,8 +2184,8 @@ public class DeptStatisticDataServiceImpl extends ServiceImpl<DeptStatisticDataM
|
||||
? sysCache.getDepartByOrgCode(orgCodeLeaf).getDepartName()
|
||||
: (
|
||||
StrUtil.isNotBlank(orgCode)
|
||||
? sysCache.getDepartByOrgCode(orgCode).getDepartName()
|
||||
: "");
|
||||
? sysCache.getDepartByOrgCode(orgCode).getDepartName()
|
||||
: "");
|
||||
LoginUser loginUser = GlobalUtils.getLoginUser();
|
||||
Boolean flag = sysBaseAPI.getFinishFlagByCode(WATCH_DEPT_DATA_STAT_DETAIL, DOING);
|
||||
if (!flag) {
|
||||
|
||||
+19
-5
@@ -300,11 +300,11 @@ public class WatchDeviceServiceImpl extends ServiceImpl<WatchDeviceMapper, Watch
|
||||
// 新增手表只能绑定给本单位的人
|
||||
LoginUser userById = sysBaseAPI.getUserById(dto.getBindUserId());
|
||||
|
||||
if (userById.getOrgCode() == null || watchDevice.getOrgCode() == null ||
|
||||
userById.getOrgCode().length() < 6 || watchDevice.getOrgCode().length() < 6 ||
|
||||
!userById.getOrgCode().substring(0, 6).equals(watchDevice.getOrgCode().substring(0, 6))) {
|
||||
return Result.error("手表只能绑定给本单位人员");
|
||||
}
|
||||
// if (userById.getOrgCode() == null || watchDevice.getOrgCode() == null ||
|
||||
// userById.getOrgCode().length() < 6 || watchDevice.getOrgCode().length() < 6 ||
|
||||
// !userById.getOrgCode().substring(0, 6).equals(watchDevice.getOrgCode().substring(0, 6))) {
|
||||
// return Result.error("手表只能绑定给本单位人员");
|
||||
// }
|
||||
|
||||
if (isDeviceAlreadyBound(watchDevice, dto)) {
|
||||
return Result.error("该设备已被绑定");
|
||||
@@ -330,6 +330,13 @@ public class WatchDeviceServiceImpl extends ServiceImpl<WatchDeviceMapper, Watch
|
||||
}
|
||||
// 更新工具信息
|
||||
watchDevice.setBindDate(dto.getBindDate());
|
||||
// 根据员工更新手表单位信息(如果单位编码大于6位,取6位)
|
||||
String orgCode = userById.getOrgCode();
|
||||
if(StrUtil.isNotBlank(orgCode) && orgCode.length() > 6){
|
||||
orgCode = orgCode.substring(0, 6);
|
||||
}
|
||||
watchDevice.setOrgCode(orgCode);
|
||||
watchDevice.setDeptId(sysCache.getDepartIdByOrgCode(orgCode));
|
||||
bindUserToDevice(watchDevice, dto);
|
||||
if (StrUtil.isNotBlank(dto.getBindUserId())) {
|
||||
// 初始化开关数据
|
||||
@@ -488,6 +495,13 @@ public class WatchDeviceServiceImpl extends ServiceImpl<WatchDeviceMapper, Watch
|
||||
updateWrapper.eq("id", watchDevice.getId());
|
||||
updateWrapper.set("bind_user_id", dto.getBindUserId());
|
||||
updateWrapper.set("bind_date", watchDevice.getBindDate());
|
||||
if(StrUtil.isNotBlank(watchDevice.getOrgCode())){
|
||||
updateWrapper.set("org_code", watchDevice.getOrgCode());
|
||||
}
|
||||
if (StrUtil.isNotBlank(watchDevice.getDeptId())){
|
||||
updateWrapper.set("dept_id", watchDevice.getDeptId());
|
||||
}
|
||||
|
||||
this.update(updateWrapper);
|
||||
}
|
||||
|
||||
|
||||
@@ -128,9 +128,9 @@ public class MyUploadUtil {
|
||||
bizPath = StrAttackFilter.filter(bizPath);
|
||||
// .tar 文件固定走 MyUpload
|
||||
if (fileName != null && fileName.endsWith(".tar")) {
|
||||
log.info("上传文件为tar文件,使用MyUploadUtil上传");
|
||||
log.info("上传文件为tar/apk文件,使用MyUploadUtil上传");
|
||||
try {
|
||||
return upload(file.getInputStream(), bizPath, fileName);
|
||||
return upload(file.getInputStream(), bizPath, fileName,true);
|
||||
} catch (Exception e) {
|
||||
log.error("upload error {}", e.getMessage(), e);
|
||||
return null;
|
||||
|
||||
@@ -185,8 +185,8 @@ public class ShiroConfig {
|
||||
|
||||
filterChainDefinitionMap.put("/version/getSysVersionDetailByPackageName", "anon");
|
||||
filterChainDefinitionMap.put("/sys/api/notice/selectIosUpdate", "anon");
|
||||
filterChainDefinitionMap.put("/sys/upload/down/**", "anon");
|
||||
filterChainDefinitionMap.put("/sys/upload/show/**", "anon");
|
||||
// filterChainDefinitionMap.put("/sys/upload/down/**", "anon");
|
||||
// filterChainDefinitionMap.put("/sys/upload/show/**", "anon");
|
||||
|
||||
// 添加自己的过滤器并且取名为jwt
|
||||
Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
|
||||
|
||||
Reference in New Issue
Block a user