项目部门关联

This commit is contained in:
lcj
2025-10-16 17:55:48 +08:00
parent aec8667edc
commit cecfb60e71
14 changed files with 157 additions and 9 deletions

View File

@ -324,6 +324,7 @@ ys7:
app-secret: 09e29c70ae1161fbc3ce2030fc09ba2e app-secret: 09e29c70ae1161fbc3ce2030fc09ba2e
job: job:
capture-enabled: false # 控制是否启用萤石抓拍任务 capture-enabled: false # 控制是否启用萤石抓拍任务
device-sync-enabled: false # 控制是否同步萤石设备
#ys7: #ys7:
# app-key: 081b0d6d5f7f4de8bc5c7fa350fb26ec # app-key: 081b0d6d5f7f4de8bc5c7fa350fb26ec
# app-secret: caa37b9f60ef02deb57e563bc190e6db # app-secret: caa37b9f60ef02deb57e563bc190e6db

View File

@ -321,12 +321,13 @@ weather:
api-host: n35rk53njv.re.qweatherapi.com api-host: n35rk53njv.re.qweatherapi.com
# dxf转 geojson 执行文件名 # dxf转 geojson 执行文件名
dxf2GeoJson: dxf2GeoJson:
file-name: main.exe file-name: main
ys7: ys7:
app-key: 3acf9f1a43dc4209841e0893003db0a2 app-key: 3acf9f1a43dc4209841e0893003db0a2
app-secret: 09e29c70ae1161fbc3ce2030fc09ba2e app-secret: 09e29c70ae1161fbc3ce2030fc09ba2e
job: job:
capture-enabled: true # 控制是否启用萤石抓拍任务 capture-enabled: true # 控制是否启用萤石抓拍任务
device-sync-enabled: true # 控制是否同步萤石设备
# 斯巴达算法 # 斯巴达算法
sparta: sparta:
url: http://119.3.204.120:8040 url: http://119.3.204.120:8040

View File

@ -5,6 +5,7 @@ import lombok.extern.slf4j.Slf4j;
import org.dromara.manager.ys7manager.Ys7Manager; import org.dromara.manager.ys7manager.Ys7Manager;
import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo; import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo;
import org.dromara.other.service.IOthYs7DeviceService; import org.dromara.other.service.IOthYs7DeviceService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -17,7 +18,8 @@ import java.util.List;
* @date 2025/6/17 9:33 * @date 2025/6/17 9:33
*/ */
@Slf4j @Slf4j
//@Component @Component
@ConditionalOnProperty(prefix = "ys7.job", name = "device-sync-enabled", havingValue = "true")
public class IncSyncYs7DeviceData { public class IncSyncYs7DeviceData {
@Resource @Resource

View File

@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.websocket.*; import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint; import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.SpringUtils;
import org.dromara.project.service.IBusAttendanceMachineService; import org.dromara.project.service.IBusAttendanceMachineService;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -466,7 +467,8 @@ public class DeviceWebSocketServer {
// 2. 发送请求 // 2. 发送请求
boolean sendSuccess = sendMessageToDevice(sn, uuid, payload); boolean sendSuccess = sendMessageToDevice(sn, uuid, payload);
if (!sendSuccess) { if (!sendSuccess) {
throw new Exception("发送请求失败设备不在线或连接异常SN: " + sn); log.error("发送请求失败设备不在线或连接异常SN: {}", sn);
throw new ServiceException("发送请求失败设备不在线或连接异常SN: " + sn);
} }
// 3. 等待响应10秒超时 // 3. 等待响应10秒超时
@ -475,6 +477,7 @@ public class DeviceWebSocketServer {
log.error("等待响应超时SN: {}UUID: {}", sn, uuid); log.error("等待响应超时SN: {}UUID: {}", sn, uuid);
responseChannels.remove(uuid); responseChannels.remove(uuid);
snToUuids.get(sn).remove(uuid); snToUuids.get(sn).remove(uuid);
log.error("等待响应超时10秒SN: {}", sn, e);
throw new Exception("等待响应超时10秒SN: " + sn, e); throw new Exception("等待响应超时10秒SN: " + sn, e);
} finally { } finally {
// 4. 清理响应通道(防止内存泄漏) // 4. 清理响应通道(防止内存泄漏)

View File

@ -0,0 +1,29 @@
package org.dromara.project.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* 项目与部门关联对象 bus_project_dept
*
* @author lilemy
* @date 2025-10-16
*/
@Data
@TableName("bus_project_dept")
public class BusProjectDept {
/**
* 项目ID
*/
@TableId(type = IdType.INPUT)
private Long projectId;
/**
* 部门ID
*/
private Long deptId;
}

View File

@ -4,6 +4,7 @@ import lombok.Data;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
/** /**
* @author lilemy * @author lilemy
@ -134,4 +135,9 @@ public class BusProjectCreateReq implements Serializable {
* 位置信息 * 位置信息
*/ */
private String position; private String position;
/**
* 所属部门列表
*/
private List<Long> deptIds;
} }

View File

@ -69,4 +69,9 @@ public class BusProjectQueryReq implements Serializable {
* 显示隐藏0显示 1隐藏 * 显示隐藏0显示 1隐藏
*/ */
private String showHidden; private String showHidden;
/**
* 部门id
*/
private Long deptId;
} }

View File

@ -8,6 +8,7 @@ import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert; import org.dromara.common.excel.convert.ExcelDictConvert;
import org.dromara.project.domain.BusProject; import org.dromara.project.domain.BusProject;
import org.dromara.project.domain.bo.Punchrange; import org.dromara.project.domain.bo.Punchrange;
import org.dromara.system.domain.vo.SysDeptVo;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
@ -212,4 +213,9 @@ public class BusProjectVo implements Serializable {
private String position; private String position;
/**
* 所属部门
*/
private List<SysDeptVo> deptList;
} }

View File

@ -0,0 +1,14 @@
package org.dromara.project.mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.project.domain.BusProjectDept;
/**
* 项目与部门关联Mapper接口
*
* @author lilemy
* @date 2025-10-16
*/
public interface BusProjectDeptMapper extends BaseMapperPlus<BusProjectDept, BusProjectDept> {
}

View File

@ -0,0 +1,13 @@
package org.dromara.project.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.dromara.project.domain.BusProjectDept;
/**
* 项目与部门关联Service接口
*
* @author lilemy
* @date 2025-10-16
*/
public interface IBusProjectDeptService extends IService<BusProjectDept> {
}

View File

@ -2,6 +2,7 @@ package org.dromara.project.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.HttpStatus; import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
@ -33,6 +34,7 @@ import java.util.stream.Collectors;
* @author lilemy * @author lilemy
* @date 2025-10-15 * @date 2025-10-15
*/ */
@Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
public class BusAttendanceMachineUserServiceImpl implements IBusAttendanceMachineUserService { public class BusAttendanceMachineUserServiceImpl implements IBusAttendanceMachineUserService {
@ -74,18 +76,20 @@ public class BusAttendanceMachineUserServiceImpl implements IBusAttendanceMachin
throw new ServiceException("所选班组与考勤机不匹配", HttpStatus.NOT_FOUND); throw new ServiceException("所选班组与考勤机不匹配", HttpStatus.NOT_FOUND);
} }
// 获取考勤机里的用户 // 获取考勤机里的用户
Set<Long> userIdList = new HashSet<>(); Set<String> userIdList = new HashSet<>();
try { try {
KqjEntity.CommonResponse response = deviceMessageSender.getAllUsers(machine.getSn()); KqjEntity.CommonResponse response = deviceMessageSender.getAllUsers(machine.getSn());
int code = response.getData().getCode(); int code = response.getData().getCode();
if (code == 0 || code == 200) { if (code == 0 || code == 200) {
log.info("获取考勤机数据成功:{}", response.getData());
String[] userIds = response.getData().getUserIds(); String[] userIds = response.getData().getUserIds();
userIdList = Arrays.stream(userIds).map(Long::parseLong).collect(Collectors.toSet()); userIdList = Arrays.stream(userIds).collect(Collectors.toSet());
} }
} catch (Exception e) { } catch (Exception e) {
log.error("获取考勤机用户失败sn{}", machine.getSn(), e);
throw new ServiceException("获取考勤机用户失败", HttpStatus.ERROR); throw new ServiceException("获取考勤机用户失败", HttpStatus.ERROR);
} }
Set<Long> finalUserIdList = userIdList; Set<String> finalUserIdList = userIdList;
return teamMemberList.stream().map(member -> { return teamMemberList.stream().map(member -> {
BusAttendanceMachineUserVo vo = new BusAttendanceMachineUserVo(); BusAttendanceMachineUserVo vo = new BusAttendanceMachineUserVo();
vo.setMachineId(req.getMachineId()); vo.setMachineId(req.getMachineId());
@ -94,7 +98,7 @@ public class BusAttendanceMachineUserServiceImpl implements IBusAttendanceMachin
vo.setUserName(member.getMemberName()); vo.setUserName(member.getMemberName());
if (CollUtil.isEmpty(finalUserIdList)) { if (CollUtil.isEmpty(finalUserIdList)) {
vo.setIdentifying(0); vo.setIdentifying(0);
} else if (finalUserIdList.contains(member.getMemberId())) { } else if (finalUserIdList.contains(member.getMemberId().toString())) {
vo.setIdentifying(1); vo.setIdentifying(1);
} else { } else {
vo.setIdentifying(0); vo.setIdentifying(0);

View File

@ -0,0 +1,20 @@
package org.dromara.project.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.dromara.project.domain.BusProjectDept;
import org.dromara.project.mapper.BusProjectDeptMapper;
import org.dromara.project.service.IBusProjectDeptService;
import org.springframework.stereotype.Service;
/**
* 项目与部门关联Service业务层处理
*
* @author lilemy
* @date 2025-10-16
*/
@RequiredArgsConstructor
@Service
public class BusProjectDeptServiceImpl extends ServiceImpl<BusProjectDeptMapper, BusProjectDept>
implements IBusProjectDeptService {
}

View File

@ -3,6 +3,7 @@ package org.dromara.project.service.impl;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.PhoneUtil; import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
@ -56,7 +57,9 @@ import org.dromara.project.mapper.BusProjectMapper;
import org.dromara.project.service.*; import org.dromara.project.service.*;
import org.dromara.quality.service.IQltKnowledgeDocumentService; import org.dromara.quality.service.IQltKnowledgeDocumentService;
import org.dromara.safety.service.IHseKnowledgeDocumentService; import org.dromara.safety.service.IHseKnowledgeDocumentService;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.domain.vo.SysDictDataVo; import org.dromara.system.domain.vo.SysDictDataVo;
import org.dromara.system.service.ISysDeptService;
import org.dromara.system.service.ISysDictDataService; import org.dromara.system.service.ISysDictDataService;
import org.dromara.workflow.service.IFlwDefinitionService; import org.dromara.workflow.service.IFlwDefinitionService;
import org.dromara.xzd.utilS.IdWorker; import org.dromara.xzd.utilS.IdWorker;
@ -147,6 +150,13 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
@Resource @Resource
private ISysDictDataService dictDataService; private ISysDictDataService dictDataService;
@Resource
private IBusProjectDeptService projectDeptService;
@Lazy
@Resource
private ISysDeptService deptService;
@Resource @Resource
@Lazy @Lazy
private ISubConstructionUserService constructionUserService; private ISubConstructionUserService constructionUserService;
@ -402,6 +412,20 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
if (!saveRelevancy) { if (!saveRelevancy) {
throw new ServiceException("新增用户与项目关联失败,数据库异常", HttpStatus.ERROR); throw new ServiceException("新增用户与项目关联失败,数据库异常", HttpStatus.ERROR);
} }
// 保存项目与部门的关联
List<Long> deptIds = req.getDeptIds();
if (CollUtil.isNotEmpty(deptIds)) {
List<BusProjectDept> projectDeptList = deptIds.stream().map(deptId -> {
BusProjectDept projectDept = new BusProjectDept();
projectDept.setDeptId(deptId);
projectDept.setProjectId(projectId);
return projectDept;
}).toList();
boolean saveBatch = projectDeptService.saveBatch(projectDeptList);
if (!saveBatch) {
throw new ServiceException("保存项目与部门的关联失败", HttpStatus.ERROR);
}
}
// 异步执行数据同步 // 异步执行数据同步
self.insertProjectSyncThing(projectId) self.insertProjectSyncThing(projectId)
.thenAccept(result -> log.info("项目[{}-{}]异步执行数据同步成功", req.getProjectName(), projectId)) .thenAccept(result -> log.info("项目[{}-{}]异步执行数据同步成功", req.getProjectName(), projectId))
@ -694,6 +718,7 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
String principal = req.getPrincipal(); String principal = req.getPrincipal();
String principalPhone = req.getPrincipalPhone(); String principalPhone = req.getPrincipalPhone();
String showHidden = req.getShowHidden(); String showHidden = req.getShowHidden();
Long deptId = req.getDeptId();
// 模糊查询 // 模糊查询
lqw.like(StringUtils.isNotBlank(projectName), BusProject::getProjectName, projectName); lqw.like(StringUtils.isNotBlank(projectName), BusProject::getProjectName, projectName);
lqw.like(StringUtils.isNotBlank(shortName), BusProject::getShortName, shortName); lqw.like(StringUtils.isNotBlank(shortName), BusProject::getShortName, shortName);
@ -713,6 +738,18 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
final Long PID = 0L; final Long PID = 0L;
lqw.eq(BusProject::getPId, PID); lqw.eq(BusProject::getPId, PID);
} }
if (ObjectUtils.isNotEmpty(deptId)) {
SysDeptVo sysDeptVo = deptService.selectDeptById(deptId);
List<Long> list = StringUtils.splitTo(sysDeptVo.getAncestors(), Convert::toLong);
List<Long> projectDepts = new ArrayList<>();
if (list.size() >= 2) {
projectDepts = projectDeptService.lambdaQuery()
.eq(BusProjectDept::getDeptId, list.get(1))
.list()
.stream().map(BusProjectDept::getProjectId).toList();
}
lqw.in(CollUtil.isNotEmpty(projectDepts), BusProject::getId, projectDepts);
}
// 排序 // 排序
lqw.orderByAsc(BusProject::getSort); lqw.orderByAsc(BusProject::getSort);
return lqw; return lqw;

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.project.mapper.BusProjectDeptMapper">
</mapper>