[update] 修改算法

This commit is contained in:
lcj
2025-07-22 09:43:33 +08:00
parent ccfe6b8f3e
commit fe7a195362
28 changed files with 1951 additions and 602 deletions

View File

@ -286,3 +286,5 @@ sparta:
# 身份证加密密钥32 位)
id-card:
encrypt-key: 7ae260d150a14027d2238a1cf80a48ef
recognizer:
url: http://192.168.110.5:50070

View File

@ -285,3 +285,5 @@ sparta:
# 身份证加密密钥32 位)
id-card:
encrypt-key: 7ae260d150a14027d2238a1cf80a48ef
recognizer:
url: http://192.168.110.5:50070

View File

@ -0,0 +1,29 @@
package org.dromara.test;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.dromara.manager.recognizermanager.RecognizerManager;
import org.dromara.manager.recognizermanager.enums.RecognizerTypeEnum;
import org.dromara.manager.recognizermanager.vo.RecognizeVo;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
/**
* @author lcj
* @date 2025/7/21 11:35
*/
@Slf4j
@SpringBootTest
public class RecognizerTest {
@Resource
private RecognizerManager recognizerManager;
@Test
void test() {
RecognizeVo recognize = recognizerManager.recognize("http://xny.yj-3d.com:7363/file/tif/20250625160218orthophoto.png", List.of(RecognizerTypeEnum.PHO));
log.info("recognize: {}", recognize);
}
}

View File

@ -0,0 +1,21 @@
package org.dromara.contractor.config;
import jakarta.annotation.Resource;
import org.dromara.contractor.interceptor.ContractorInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Resource
private ContractorInterceptor contractorInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(contractorInterceptor)
.addPathPatterns("/contractor/**") // 拦截所有 /contractor 开头
.excludePathPatterns("/contractor/contractor/**"); // 排除具体路径
}
}

View File

@ -170,7 +170,7 @@ public class SubConstructionUserController extends BaseController {
/**
* 施工人员迁移
*/
@SaCheckPermission("contractor:constructionUser:edit")
@SaCheckPermission("contractor:constructionUser:migration")
@Log(title = "施工人员", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/change/project")

View File

@ -1,5 +1,6 @@
package org.dromara.contractor.domain.dto.subcontract;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
@ -55,6 +56,7 @@ public class SubSubcontractCreateReq implements Serializable {
/**
* 合同时间
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date contractTime;
/**

View File

@ -1,5 +1,6 @@
package org.dromara.contractor.domain.dto.subcontract;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
@ -60,6 +61,7 @@ public class SubSubcontractUpdateReq implements Serializable {
/**
* 合同时间
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date contractTime;
/**

View File

@ -0,0 +1,84 @@
package org.dromara.contractor.interceptor;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.web.filter.RepeatedlyRequestWrapper;
import org.dromara.system.domain.enums.SysDeptTypeEnum;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.service.ISysDeptService;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import java.io.BufferedReader;
import java.util.Arrays;
import java.util.Map;
/**
* @author lcj
* @date 2025/7/21 15:57
*/
@Component
public class ContractorInterceptor implements HandlerInterceptor {
@Resource
private ISysDeptService deptService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Long deptId = LoginHelper.getDeptId();
if (ObjectUtil.isNotNull(deptId)) {
SysDeptVo deptVo = deptService.selectDeptById(deptId);
if (deptVo.getDeptType().equals(SysDeptTypeEnum.CONTRACT.getCode())) {
// 在请求前处理逻辑
System.out.println("拦截到了 /contractor/** 请求:" + request.getRequestURI());
Long contractorId = deptVo.getContractorId();
if (isJsonRequest(request)) {
String jsonParam = "";
if (request instanceof RepeatedlyRequestWrapper) {
BufferedReader reader = request.getReader();
jsonParam = IoUtil.read(reader);
}
JSONObject jsonObject = JSONUtil.parseObj(jsonParam);
contractorId = jsonObject.getLong("contractorId");
} else {
Map<String, String[]> parameterMap = request.getParameterMap();
if (MapUtil.isNotEmpty(parameterMap)) {
String[] contractorIds = parameterMap.get("contractorId");
if (contractorIds != null && contractorIds.length != 0 && StringUtils.isNotBlank(contractorIds[0])) {
contractorId = Long.valueOf(Arrays.asList(contractorIds).getFirst());
}
}
}
if (ObjectUtil.isNull(contractorId) || !contractorId.equals(deptVo.getContractorId())) {
throw new ServiceException("无访问权限");
}
}
}
return true; // 返回 true 放行false 拦截
}
/**
* 判断本次请求的数据类型是否为json
*
* @param request request
* @return boolean
*/
private boolean isJsonRequest(HttpServletRequest request) {
String contentType = request.getContentType();
if (contentType != null) {
return StringUtils.startsWithIgnoreCase(contentType, MediaType.APPLICATION_JSON_VALUE);
}
return false;
}
}

View File

@ -82,8 +82,16 @@ public class SubContractorServiceImpl extends ServiceImpl<SubContractorMapper, S
*/
@Override
public TableDataInfo<SubContractorVo> queryPageList(SubContractorQueryReq req, PageQuery pageQuery) {
LambdaQueryWrapper<SubContractor> lqw = this.buildQueryWrapper(req);
Long deptId = LoginHelper.getDeptId();
if (deptId != null) {
SysDept dept = deptMapper.selectById(deptId);
if (dept.getDeptType().equals(SysDeptTypeEnum.CONTRACT.getCode())) {
lqw.eq(SubContractor::getId, dept.getContractorId());
}
}
// 查询数据库
Page<SubContractor> result = this.page(pageQuery.build(), this.buildQueryWrapper(req));
Page<SubContractor> result = this.page(pageQuery.build(), lqw);
return TableDataInfo.build(this.getVoPage(result));
}

View File

@ -0,0 +1,14 @@
package org.dromara.manager.recognizermanager;
/**
* @author lcj
* @date 2025/7/21 10:33
*/
public interface RecognizerConstant {
/**
* 识别 api 路径
*/
String RECOGNIZE_API_PATH_POST = "/detect_image";
}

View File

@ -0,0 +1,124 @@
package org.dromara.manager.recognizermanager;
import cn.hutool.core.io.FileUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.dromara.manager.recognizermanager.enums.RecognizerTypeEnum;
import org.dromara.manager.recognizermanager.vo.RecognizeImageStreamResult;
import org.dromara.manager.recognizermanager.vo.RecognizeTargetVo;
import org.dromara.manager.recognizermanager.vo.RecognizeVo;
import org.springframework.stereotype.Component;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.FileNameMap;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLConnection;
import java.util.List;
/**
* @author lcj
* @date 2025/7/21 10:56
*/
@Slf4j
@Component
public class RecognizerManager {
@Resource
private RecognizerProperties recognizerProperties;
/**
* 识别图片
*
* @param capUrl 图片地址
* @param recTypeList 识别类型
* @param extract 是否返回图片
* @return 识别结果
*/
public RecognizeVo recognize(String capUrl, List<RecognizerTypeEnum> recTypeList, Boolean extract) {
String recType = RecognizerTypeEnum.joinRecTypes(recTypeList);
return RecognizerUtils.recognize(recognizerProperties.getUrl(), capUrl, recType, extract);
}
/**
* 识别图片
*
* @param capUrl 图片地址
* @param recTypeList 识别类型
* @return 识别结果
*/
public RecognizeVo recognize(String capUrl, List<RecognizerTypeEnum> recTypeList) {
return recognize(capUrl, recTypeList, false);
}
/**
* 绘制图片
*
* @param imgUrl 图片地址
* @param targets 识别结果
* @return 绘制后的图片
*/
public RecognizeImageStreamResult drawImageToStream(String imgUrl, List<RecognizeTargetVo> targets) throws IOException, URISyntaxException {
// 1. 加载图片
URI uri = new URI(imgUrl);
BufferedImage image = ImageIO.read(uri.toURL());
// 2. 开始绘图
Graphics2D g = image.createGraphics();
g.setColor(Color.RED);
g.setStroke(new BasicStroke(5));
// 设置中文兼容字体(或使用指定字体)
g.setFont(new Font("SansSerif", Font.BOLD, 18));
for (RecognizeTargetVo target : targets) {
int x = target.getLeftTopPoint().get(0);
int y = target.getLeftTopPoint().get(1);
int w = target.getSize().get(0);
int h = target.getSize().get(1);
// 画矩形框
g.drawRect(x, y, w, h);
// 写文字(类型 + 置信度)
String label = target.getType() + " (" + String.format("%.2f", target.getScore()) + ")";
g.drawString(label, x, y - 5);
}
g.dispose();
// 3. 输出为 InputStream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String filename = extractFilename(imgUrl);
String suffix = FileUtil.getSuffix(filename);
ImageIO.write(image, suffix == null ? "jpg" : suffix, baos);
return new RecognizeImageStreamResult(new ByteArrayInputStream(baos.toByteArray()), baos.size(), getContentTypeByFilename(filename));
}
/**
* 提取文件名
*
* @param url 文件路径
* @return 文件名
*/
private static String extractFilename(String url) {
int start = url.lastIndexOf("/") + 1;
int end = url.indexOf("?", start);
if (end == -1) {
return url.substring(start);
}
if (start > 0 && end > start) {
return url.substring(start, end);
}
return null;
}
/**
* 根据文件名获取文件类型
*
* @param filename 文件名
* @return 文件类型
*/
private static String getContentTypeByFilename(String filename) {
FileNameMap fileNameMap = URLConnection.getFileNameMap();
return fileNameMap.getContentTypeFor(filename);
}
}

View File

@ -0,0 +1,21 @@
package org.dromara.manager.recognizermanager;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author lcj
* @date 2025/7/21 10:39
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "recognizer")
public class RecognizerProperties {
/**
* 请求地址
*/
private String url;
}

View File

@ -0,0 +1,69 @@
package org.dromara.manager.recognizermanager;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.manager.recognizermanager.enums.RecognizerHasTargetEnum;
import org.dromara.manager.recognizermanager.vo.RecognizeTargetVo;
import org.dromara.manager.recognizermanager.vo.RecognizeVo;
import java.util.HashMap;
import java.util.List;
/**
* @author lcj
* @date 2025/7/21 10:41
*/
@Slf4j
public class RecognizerUtils {
/**
* 识别图片
*
* @param host 域名
* @param capUrl 在线图片地址
* @param type 识别算法模型,多选模式每个参数之间用 "," 隔开例
* @param extract 是否返回图片
* @return 识别结果
*/
public static RecognizeVo recognize(String host, String capUrl, String type, Boolean extract) {
if (StringUtils.isAnyBlank(host, capUrl, type)) {
throw new ServiceException("图片识别参数为空", HttpStatus.HTTP_BAD_REQUEST);
}
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("type", type);
paramMap.put("url", capUrl);
paramMap.put("extract", extract != null && extract ? "true" : "false");
String errorMsg = "图片识别请求失败";
String url = host + RecognizerConstant.RECOGNIZE_API_PATH_POST;
try (HttpResponse response = HttpRequest.post(url)
.body(JSONUtil.toJsonStr(paramMap))
.execute()) {
if (!response.isOk()) {
log.error("{}{}", errorMsg, response.getStatus());
throw new ServiceException(errorMsg + response.getStatus());
}
String body = response.body();
if (body == null) {
log.error("{}{}", errorMsg, "返回参数为空");
}
JSONObject result = JSONUtil.parseObj(response.body());
log.info("图片识别请求成功:{}", body);
RecognizeVo recognizeVo = new RecognizeVo();
Integer hasTarget = result.getInt("hasTarget");
recognizeVo.setHasTarget(hasTarget);
if (hasTarget.equals(RecognizerHasTargetEnum.YES.getValue())) {
recognizeVo.setOriginalImgSize(result.getJSONArray("originalImgSize").toList(Integer.class));
List<RecognizeTargetVo> targetList = JSONUtil.toList(result.getJSONArray("targets"), RecognizeTargetVo.class);
recognizeVo.setTargets(targetList);
}
return recognizeVo;
}
}
}

View File

@ -0,0 +1,23 @@
package org.dromara.manager.recognizermanager.enums;
import lombok.Getter;
/**
* @author lcj
* @date 2025/7/21 10:53
*/
@Getter
public enum RecognizerHasTargetEnum {
YES("", 1),
NO("", 0);
private final String text;
private final int value;
RecognizerHasTargetEnum(String text, int value) {
this.text = text;
this.value = value;
}
}

View File

@ -0,0 +1,60 @@
package org.dromara.manager.recognizermanager.enums;
import lombok.Getter;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author lcj
* @date 2025/7/21 10:14
*/
@Getter
public enum RecognizerTypeEnum {
HARDHAT("安全帽识别", "hardhat", ""),
VEST("反光背心", "vest", "1"),
SMOKING("吸烟识别", "smoking", "3"),
FIRE("火焰识别", "fire", "2"),
PHO("光伏板识别", "pho", ""),
SHELVES("光伏板支架识别", "shelves", ""),
PILE("光伏板立柱识别", "pile", ""),
HOLE("", "hole", "");
private final String text;
private final String value;
/**
* 描述对应字典violation_level_type
*/
private final String code;
RecognizerTypeEnum(String text, String value, String code) {
this.text = text;
this.value = value;
this.code = code;
}
public static RecognizerTypeEnum fromValue(String value) {
for (RecognizerTypeEnum type : RecognizerTypeEnum.values()) {
if (type.getValue().equals(value)) {
return type;
}
}
return null;
}
/**
* 将多个 RecognizerTypeEnum 拼接为接口识别参数字符串(","分隔)
*/
public static String joinRecTypes(List<RecognizerTypeEnum> types) {
if (types == null || types.isEmpty()) {
return "";
}
return types.stream()
.map(RecognizerTypeEnum::getValue)
.collect(Collectors.joining(","));
}
}

View File

@ -0,0 +1,33 @@
package org.dromara.manager.recognizermanager.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.InputStream;
/**
* @author lcj
* @date 2025/7/21 10:59
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RecognizeImageStreamResult {
/**
* 图片输入流
*/
private InputStream inputStream;
/**
* 图片长度
*/
private long length;
/**
* 图片类型
*/
private String contentType;
}

View File

@ -0,0 +1,38 @@
package org.dromara.manager.recognizermanager.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author lcj
* @date 2025/7/21 10:43
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RecognizeTargetVo {
/**
* 目标类型
*/
private String type;
/**
* 目标外接矩形像素
*/
private List<Integer> size;
/**
* 目标在画面中左上角位置信息
*/
private List<Integer> leftTopPoint;
/**
* 置信度得分0~1
*/
private Double score;
}

View File

@ -0,0 +1,29 @@
package org.dromara.manager.recognizermanager.vo;
import lombok.Data;
import java.util.List;
/**
* @author lcj
* @date 2025/7/21 10:42
*/
@Data
public class RecognizeVo {
/**
* 是否监测到目标10
*/
private Integer hasTarget;
/**
* 原始图片尺寸([宽,高]ex[1920,1080]
*/
private List<Integer> originalImgSize;
/**
* 目标信息
*/
private List<RecognizeTargetVo> targets;
}

View File

@ -14,12 +14,14 @@ import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.oss.core.OssClient;
import org.dromara.common.oss.factory.OssFactory;
import org.dromara.manager.spartamanager.SpartaManager;
import org.dromara.manager.recognizermanager.RecognizerManager;
import org.dromara.manager.recognizermanager.enums.RecognizerHasTargetEnum;
import org.dromara.manager.recognizermanager.enums.RecognizerTypeEnum;
import org.dromara.manager.recognizermanager.vo.RecognizeImageStreamResult;
import org.dromara.manager.recognizermanager.vo.RecognizeTargetVo;
import org.dromara.manager.recognizermanager.vo.RecognizeVo;
import org.dromara.manager.spartamanager.enums.SpartaHasTargetEnum;
import org.dromara.manager.spartamanager.enums.SpartaRecTypeEnum;
import org.dromara.manager.spartamanager.vo.ImageStreamResult;
import org.dromara.manager.spartamanager.vo.SpartaRecognizeVo;
import org.dromara.manager.spartamanager.vo.SpartaTargetVo;
import org.dromara.other.constant.Ys7DeviceImgConstant;
import org.dromara.other.domain.OthYs7DeviceImg;
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgCreateByCapture;
@ -57,7 +59,7 @@ public class OthYs7DeviceImgServiceImpl extends ServiceImpl<OthYs7DeviceImgMappe
private ISysOssService ossService;
@Resource
private SpartaManager spartaManager;
private RecognizerManager recognizerManager;
@Resource
private IHseRecognizeRecordService recognizeRecordService;
@ -210,21 +212,21 @@ public class OthYs7DeviceImgServiceImpl extends ServiceImpl<OthYs7DeviceImgMappe
othYs7DeviceImg.setDeviceName(img.getDeviceName());
othYs7DeviceImg.setUrl(ossUrl);
// 将抓取的图片进行识别
List<SpartaRecTypeEnum> recTypes = List.of(SpartaRecTypeEnum.HEAD, SpartaRecTypeEnum.SMOKE);
SpartaRecognizeVo recognizeVo = spartaManager.recognize(ossUrl, recTypes);
List<RecognizerTypeEnum> recTypes = List.of(RecognizerTypeEnum.HARDHAT, RecognizerTypeEnum.SMOKING, RecognizerTypeEnum.FIRE);
RecognizeVo recognizeVo = recognizerManager.recognize(ossUrl, recTypes);
if (recognizeVo != null && recognizeVo.getHasTarget().equals(SpartaHasTargetEnum.YES.getValue())) {
// 记录识别信息
HseRecognizeRecordCreateDto record = new HseRecognizeRecordCreateDto();
record.setCreateTime(new Date());
List<SpartaTargetVo> targets = recognizeVo.getTargets();
List<RecognizeTargetVo> targets = recognizeVo.getTargets();
othYs7DeviceImg.setTargets(JSONUtil.toJsonStr(targets));
othYs7DeviceImg.setImgSize(JSONUtil.toJsonStr(recognizeVo.getOriginalImgSize()));
othYs7DeviceImg.setIsRecognize(SpartaHasTargetEnum.YES.getValue());
List<String> recTypeList = targets.stream().map(SpartaTargetVo::getType).distinct().toList();
othYs7DeviceImg.setIsRecognize(RecognizerHasTargetEnum.YES.getValue());
List<String> recTypeList = targets.stream().map(RecognizeTargetVo::getType).distinct().toList();
othYs7DeviceImg.setRecType(JSONUtil.toJsonStr(recTypeList));
String targetUrl = null;
try {
ImageStreamResult imageStreamResult = spartaManager.drawImageToStream(url, targets);
RecognizeImageStreamResult imageStreamResult = recognizerManager.drawImageToStream(url, targets);
InputStream inputStream = imageStreamResult.getInputStream();
String contentType = imageStreamResult.getContentType();
long length = imageStreamResult.getLength();
@ -235,7 +237,7 @@ public class OthYs7DeviceImgServiceImpl extends ServiceImpl<OthYs7DeviceImgMappe
othYs7DeviceImg.setRecognizeUrl(targetUrl);
}
} catch (Exception e) {
log.error("图片识别失败", e);
log.error("图片绘制失败", e);
}
record.setTargets(targets);
record.setDeviceSerial(deviceSerial);

View File

@ -3,7 +3,7 @@ package org.dromara.safety.domain.dto.recognizerecord;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.dromara.manager.spartamanager.vo.SpartaTargetVo;
import org.dromara.manager.recognizermanager.vo.RecognizeTargetVo;
import java.util.Date;
import java.util.List;
@ -50,6 +50,6 @@ public class HseRecognizeRecordCreateDto {
/**
* 目标信息
*/
private List<SpartaTargetVo> targets;
private List<RecognizeTargetVo> targets;
}

View File

@ -12,8 +12,8 @@ import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.manager.recognizermanager.vo.RecognizeTargetVo;
import org.dromara.manager.spartamanager.enums.SpartaRecTypeEnum;
import org.dromara.manager.spartamanager.vo.SpartaTargetVo;
import org.dromara.project.service.IBusProjectService;
import org.dromara.safety.domain.HseRecognizeRecord;
import org.dromara.safety.domain.dto.recognizerecord.HseRecognizeRecordCreateDto;
@ -107,9 +107,9 @@ public class HseRecognizeRecordServiceImpl extends ServiceImpl<HseRecognizeRecor
if (projectId == null) {
entity.setRemark("该摄像头暂未分配到项目中");
}
List<SpartaTargetVo> targets = record.getTargets();
List<RecognizeTargetVo> targets = record.getTargets();
List<String> codeList = targets.stream()
.map(SpartaTargetVo::getType).distinct()
.map(RecognizeTargetVo::getType).distinct()
.map(SpartaRecTypeEnum::fromValue).filter(Objects::nonNull)
.map(SpartaRecTypeEnum::getCode).filter(Objects::nonNull)
.toList();

View File

@ -2,6 +2,7 @@ package org.dromara.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.tree.Tree;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.domain.R;
@ -56,6 +57,16 @@ public class SysDeptController extends BaseController {
return R.ok(depts);
}
/**
* 根据项目id获取部门树以及岗位列表
*/
@SaCheckPermission("system:dept:treeByProjectId")
@GetMapping("/list/treeByProjectId/{projectId}")
public R<List<Tree<Long>>> listTreeByProjectId(@PathVariable Long projectId) {
List<Tree<Long>> tree = deptService.buildDeptTreeByProjectId(projectId);
return R.ok(tree);
}
/**
* 根据部门编号获取详细信息
*

View File

@ -23,10 +23,12 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.web.core.BaseController;
import org.dromara.contractor.service.ISubContractorService;
import org.dromara.system.domain.bo.SysDeptBo;
import org.dromara.system.domain.bo.SysPostBo;
import org.dromara.system.domain.bo.SysRoleBo;
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.domain.enums.SysDeptTypeEnum;
import org.dromara.system.domain.vo.*;
import org.dromara.system.listener.SysUserImportListener;
import org.dromara.system.service.*;
@ -54,6 +56,7 @@ public class SysUserController extends BaseController {
private final ISysPostService postService;
private final ISysDeptService deptService;
private final ISysTenantService tenantService;
private final ISubContractorService contractorService;
/**
* 获取用户列表
@ -117,6 +120,14 @@ public class SysUserController extends BaseController {
userInfoVo.setUser(user);
userInfoVo.setPermissions(loginUser.getMenuPermission());
userInfoVo.setRoles(loginUser.getRolePermission());
Long deptId = user.getDeptId();
if (ObjectUtil.isNotNull(deptId)) {
SysDeptVo deptVo = deptService.selectDeptById(deptId);
Long contractorId = deptVo.getContractorId();
if (deptVo.getDeptType().equals(SysDeptTypeEnum.CONTRACT.getCode()) && ObjectUtil.isNotNull(contractorId)) {
userInfoVo.setContractorId(contractorId);
}
}
return R.ok(userInfoVo);
}

View File

@ -27,4 +27,9 @@ public class UserInfoVo {
*/
private Set<String> roles;
/**
* 分包公司ID
*/
private Long contractorId;
}

View File

@ -36,6 +36,14 @@ public interface ISysDeptService {
*/
List<Tree<Long>> buildDeptTreeSelect(List<SysDeptVo> depts);
/**
* 构建前端所需要下拉树结构
*
* @param projectId 项目id
* @return 下拉树结构列表
*/
List<Tree<Long>> buildDeptTreeByProjectId(Long projectId);
/**
* 根据角色ID查询部门树信息
*

View File

@ -28,12 +28,15 @@ import org.dromara.project.domain.vo.project.BusProjectVo;
import org.dromara.project.service.IBusProjectService;
import org.dromara.project.service.IBusUserProjectRelevancyService;
import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.SysPost;
import org.dromara.system.domain.SysRole;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.SysDeptBo;
import org.dromara.system.domain.enums.SysDeptTypeEnum;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.domain.vo.SysPostVo;
import org.dromara.system.mapper.SysDeptMapper;
import org.dromara.system.mapper.SysPostMapper;
import org.dromara.system.mapper.SysRoleMapper;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.ISysDeptService;
@ -44,6 +47,8 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 部门管理 服务实现
@ -58,6 +63,7 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
private final SysDeptMapper baseMapper;
private final SysRoleMapper roleMapper;
private final SysUserMapper userMapper;
private final SysPostMapper postMapper;
private final IBusProjectService projectService;
private final ISubContractorService contractorService;
private final IBusUserProjectRelevancyService userProjectRelevancyService;
@ -138,6 +144,60 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
return treeList;
}
/**
* 构建前端所需要下拉树结构
*
* @param projectId 项目id
* @return 下拉树结构列表
*/
@Override
public List<Tree<Long>> buildDeptTreeByProjectId(Long projectId) {
SysDept dept = baseMapper.selectOne(
new LambdaQueryWrapper<>(SysDept.class)
.eq(SysDept::getProjectId, projectId)
.eq(SysDept::getDeptType, SysDeptTypeEnum.PROJECT.getCode())
.eq(SysDept::getStatus, SystemConstants.NORMAL)
);
if (dept == null) {
return List.of();
}
List<Long> deptIds = Stream.concat(
Arrays.stream(dept.getAncestors().split(","))
.filter(StringUtils::isNotBlank)
.map(Long::parseLong),
Stream.of(dept.getDeptId())
).toList();
List<SysDeptVo> deptVoList = baseMapper.selectVoByIds(deptIds);
List<SysPostVo> postVos = postMapper.selectVoList(
new LambdaQueryWrapper<>(SysPost.class)
.in(SysPost::getDeptId, deptIds)
.eq(SysPost::getStatus, SystemConstants.NORMAL)
);
Map<Long, List<SysPostVo>> postVoMap = postVos.stream().collect(Collectors.groupingBy(SysPostVo::getDeptId));
// 获取当前列表中每一个节点的parentId然后在列表中查找是否有id与其parentId对应若无对应则表明此时节点列表中该节点在当前列表中属于顶级节点
List<Tree<Long>> treeList = CollUtil.newArrayList();
for (SysDeptVo d : deptVoList) {
Long parentId = d.getParentId();
SysDeptVo sysDeptVo = StreamUtils.findFirst(deptVoList, it -> it.getDeptId().longValue() == parentId);
if (ObjectUtil.isNull(sysDeptVo)) {
List<Tree<Long>> trees = TreeBuildUtils.build(deptVoList, parentId, (deptVo, tree) -> {
Long deptId = deptVo.getDeptId();
tree.setId(deptId)
.setParentId(deptVo.getParentId())
.setName(deptVo.getDeptName())
.setWeight(deptVo.getOrderNum())
.putExtra("disabled", SystemConstants.DISABLE.equals(deptVo.getStatus()));
tree.putExtra("deptType", deptVo.getDeptType());
tree.putExtra("postVoList", postVoMap.get(deptId));
}
);
Tree<Long> tree = StreamUtils.findFirst(trees, it -> it.getId().longValue() == d.getDeptId());
treeList.add(tree);
}
}
return treeList;
}
/**
* 根据角色ID查询部门树信息
*

File diff suppressed because it is too large Load Diff

View File

@ -1561,3 +1561,37 @@ CREATE TABLE `dro_drone_config`
index `idx_project_id` (`project_id` asc) using btree comment '项目id'
) comment '无人机配置' collate = utf8mb4_unicode_ci;
DROP TABLE IF EXISTS `hse_violation_record`;
CREATE TABLE `hse_violation_record`
(
`id` bigint not null auto_increment comment '主键id',
`project_id` bigint not null comment '项目id',
`level_id` bigint DEFAULT NULL COMMENT '违章等级主键ID',
`level` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '违章等级(字符串)',
`tour_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '违章类型(字典)',
`tour_id` bigint DEFAULT NULL COMMENT '违章详情关联bus_tour',
`data_source` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据来源violation_record_data_source',
`select_people` bigint DEFAULT NULL COMMENT '选择人后台用户ID',
`openid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'openid施工人员',
`status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '1' COMMENT '工单状态1通知 2整改 3复查',
`processing_period` varchar(22) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '处理期限(要求)',
`processing_period_practical` varchar(22) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '处理期限(实际)',
`measure` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '整改措施',
`review` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '复查情况',
`review_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '复查状态1通过 2未通过',
`rectification_time` datetime DEFAULT NULL COMMENT '整改时间',
`review_time` datetime DEFAULT NULL COMMENT '复查时间',
`picture` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '图片',
`processing_time` date DEFAULT NULL COMMENT '处理日期',
`is_dispose` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '1' COMMENT '是否处理1待处理 2已处理',
`labor_date` varchar(22) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '人工日期(数据来源人工才会有此日期)',
`sxt_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '摄像头名称',
`remark` text null comment '备注',
`create_by` bigint null comment '创建者',
`update_by` bigint null comment '更新者',
`create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间',
`update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间',
primary key (`id`) using btree,
index `idx_project_id` (`project_id` asc) using btree comment '项目id'
) comment '违规记录' collate = utf8mb4_unicode_ci;