[update] 修改算法
This commit is contained in:
		@ -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/**"); // 排除具体路径
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -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")
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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";
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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(","));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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 {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 是否监测到目标:1:是;0:否
 | 
			
		||||
     */
 | 
			
		||||
    private Integer hasTarget;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 原始图片尺寸([宽,高]),ex:[1920,1080]
 | 
			
		||||
     */
 | 
			
		||||
    private List<Integer> originalImgSize;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 目标信息
 | 
			
		||||
     */
 | 
			
		||||
    private List<RecognizeTargetVo> targets;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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();
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据部门编号获取详细信息
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -27,4 +27,9 @@ public class UserInfoVo {
 | 
			
		||||
     */
 | 
			
		||||
    private Set<String> roles;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 分包公司ID
 | 
			
		||||
     */
 | 
			
		||||
    private Long contractorId;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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查询部门树信息
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
@ -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查询部门树信息
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user