“mitao”
2026-01-28 0a0bbb964267bf53b35ae67dc946b7e5d1aaa8e8
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ProjectController.java
@@ -1,28 +1,47 @@
package com.ruoyi.web.controller.api;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.icbc.hsm.utils.StringUtil;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.dto.EditHiddenDangerResponsiblePersonDto;
import com.ruoyi.system.enums.DeviceType;
import com.ruoyi.system.model.*;
import com.ruoyi.system.model.Record;
import com.ruoyi.system.query.DeviceDetailCheckListQuery;
import com.ruoyi.system.query.DeviceListQuery;
import com.ruoyi.system.query.HiddenDangerListQuery;
import com.ruoyi.system.query.*;
import com.ruoyi.system.service.*;
import com.ruoyi.system.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.var;
import io.swagger.annotations.*;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.parsing.Problem;
import org.springframework.core.io.InputStreamResource;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.groupingBy;
@RestController
@RequestMapping("/project")
@@ -45,6 +64,75 @@
    @Autowired
    private RecordService recordService;
    @Autowired
    private CheckService checkService;
    @Autowired
    private OnDutyService onDutyService;
    @Autowired
    private PositionService positionService;
    @Autowired
    private PlanService planService;
    @Autowired
    private ScreenAccountService screenAccountService;
    @Autowired
    private ProjectProgressService projectProgressService;
    @ApiOperation(value = "获取项目/委托方列表",response = LoginNameVo.class)
    @GetMapping("/getLoginNameVoList")
    public R<List<LoginNameVo>> getProjectList(@RequestParam Integer userId) {
        ScreenAccount screenAccount = screenAccountService.getById(userId);
        String clientProjectIds = screenAccount.getClientProjectIds();
        if(screenAccount.getType()==1){
            // 委托方
            List<LoginNameVo> list = screenAccountService.getLoginClient(clientProjectIds);
            return R.ok(list);
        }else {
            // 项目
            List<LoginNameVo> list = screenAccountService.getLoginProject(clientProjectIds);
            return R.ok(list);
        }
    }
    @ApiOperation(value = "获取项目最新进度",response = ProjectProgress.class)
    @GetMapping("/getProjectProgress/{projectId}")
    public R<ProjectProgress> getProjectProgress(@PathVariable Integer projectId) {
        ProjectProgress projectProgress = projectProgressService.getOne(new LambdaQueryWrapper<ProjectProgress>().eq(ProjectProgress::getProjectId, projectId).eq(ProjectProgress::getDeleted,0).orderByDesc(ProjectProgress::getTime).last("limit 1"));
        return R.ok(projectProgress);
    }
    @ApiOperation(value = "获取项目进度历史列表",response = ProjectProgress.class)
    @PostMapping("/getProjectProgressList")
    public R<Page<ProjectProgress>> getProjectProgressList(@Valid @RequestBody ProjectProgressQuery query) {
        LambdaQueryWrapper<ProjectProgress> wrapper = new LambdaQueryWrapper<ProjectProgress>().eq(ProjectProgress::getProjectId, query.getProjectId()).eq(ProjectProgress::getDeleted, 0);
        if(query.getContent()!=null && !query.getContent().isEmpty()){
            wrapper.like(ProjectProgress::getDetail, query.getContent());
        }
        if(query.getStartTime()!=null && !query.getStartTime().isEmpty()){
            wrapper.ge(ProjectProgress::getTime, query.getStartTime());
        }
        if(query.getEndTime()!=null && !query.getEndTime().isEmpty()){
            wrapper.le(ProjectProgress::getTime, query.getEndTime());
        }
        wrapper.orderByDesc(ProjectProgress::getTime);
        Page<ProjectProgress> page = projectProgressService.page(new Page<>(query.getPageNum(), query.getPageSize()),wrapper);
        return R.ok(page);
    }
    @ApiOperation(value = "获取项目进度详情",response = ProjectProgress.class)
    @GetMapping("/getProjectProgressDetail/{id}")
    public R<ProjectProgress> getProjectProgressDetail(@PathVariable Integer id) {
        return R.ok(projectProgressService.getById(id));
    }
    @ApiOperation(value = "获取项目详情",response = Project.class)
@@ -57,7 +145,7 @@
        List<String> properties = deviceUsageService.getDeviceUsageList(id);
        projectVo.setProperties( properties);
        ProjectInfo projectInfo = projectInfoService.getOne(new LambdaUpdateWrapper<ProjectInfo>().eq(ProjectInfo::getProjectId, id));
        ProjectInfo projectInfo = projectInfoService.getOne(new LambdaUpdateWrapper<ProjectInfo>().eq(ProjectInfo::getProjectId, id).eq(ProjectInfo::getDeleted,false).orderByDesc(ProjectInfo::getCreateTime).last("limit 1"));
        if(projectInfo!=null){
            projectVo.setProgress(projectInfo.getProgress());
        }
@@ -66,11 +154,17 @@
        if(task!=null){
            projectVo.setCheckTime(task.getUpdateTime());
        }
        List<DeviceCountVo> list = deviceUsageService.getProjectDeviceCount(id);
        list.forEach(item->{
            DeviceType value = DeviceType.values()[item.getType()];
            item.setName(value.getDesc());
        });
        projectVo.setDeviceCountVos(list);
        return R.ok(projectVo);
    }
    @ApiOperation(value = "获取项目隐患数量",response = Project.class)
    @ApiOperation(value = "获取项目隐患数量",response = HiddenDangerVo.class)
    @GetMapping("/getProjectHiddenDangerCount/{id}")
    public R<HiddenDangerVo> getProjectHiddenDangerCount(@PathVariable Integer id) {
        HiddenDangerVo hiddenDangerVo = new HiddenDangerVo();
@@ -85,6 +179,13 @@
            hiddenDangerVo.setUnRectified(records.size()-rectified);
        }
        return R.ok(hiddenDangerVo);
    }
    @ApiOperation(value = "获取设备数量",response = DeviceCountVo.class)
    @GetMapping("/getProjectDeviceCount/{id}")
    public R<List<DeviceCountVo>> getProjectDeviceCount(@PathVariable Integer id) {
        List<DeviceCountVo> list = deviceUsageService.getProjectDeviceCount(id);
        return R.ok(list);
    }
@@ -118,10 +219,10 @@
    }
    @ApiOperation(value = "获取隐患详情")
    @GetMapping("/getHiddenDangerDetail/{problemId}")
    public R<?> getHiddenDangerDetail(@PathVariable Integer problemId) {
        var record = recordService.getHiddenDangerDetail(problemId);
    @ApiOperation(value = "获取隐患详情",response = ProblemVo.class)
    @GetMapping("/getHiddenDangerDetail/{id}")
    public R<ProblemVo> getHiddenDangerDetail(@PathVariable Integer id) {
        ProblemVo record = recordService.getHiddenDangerDetail(id);
        return R.ok(record);
    }
@@ -137,7 +238,7 @@
    }
    @ApiOperation(value = "获取设备详情检查列表")
    @ApiOperation(value = "获取检查计划列表",response = DeviceDetailCheckListVo.class)
    @PostMapping("/getDeviceDetailCheckList")
    public R<Page<DeviceDetailCheckListVo>> getDeviceDetailCheckList(@RequestBody DeviceDetailCheckListQuery query) {
        Page<DeviceDetailCheckListVo> page = new Page<>(query.getPageNum(), query.getPageSize());
@@ -145,4 +246,266 @@
        page.setRecords(list);
        return R.ok(page);
    }
    @ApiOperation(value = "获取检查资料列表")
    @GetMapping("/getDeviceDetailCheckPlanList")
    public R<List<Check>> getDeviceDetailCheckPlanList(@RequestParam Integer planId) {
        List<Check> list = checkService.list(new LambdaQueryWrapper<Check>().eq(Check::getPlanId,planId).orderByDesc(Check::getTime));
        if(!list.isEmpty()){
            List<Integer> planIds = list.stream().map(Check::getPlanId).toList();
            List<Plan> plans = planService.listByIds(planIds);
            List<Integer> projectIds = list.stream().map(Check::getProjectId).toList();
            List<Project> projects = projectService.listByIds(projectIds);
            list.forEach(check -> {
                check.setPlanName(Objects.requireNonNull(plans.stream().filter(plan -> plan.getId().equals(check.getPlanId())).findFirst().orElse(null)).getName());
                check.setProjectName(Objects.requireNonNull(projects.stream().filter(project -> project.getId().equals(check.getProjectId())).findFirst().orElse(null)).getName());
            });
        }
        return R.ok(list);
    }
    @ApiOperation(value = "获取检查资料详情")
    @GetMapping("/getDeviceDetailCheckPlanDetail")
    public R<Check> getDeviceDetailCheckPlanDetail(@RequestParam Integer id) {
        Check check = checkService.getDeviceDetailCheckPlanDetail(id);
        return R.ok(check);
    }
    @ApiOperation(value = "获取大屏人员在岗信息")
    @GetMapping("/getProjectPersonInfo")
    public R<List<ProjectPersonInfoVo>> getProjectPersonInfo(@RequestParam Integer projectId) {
        List<OnDuty> list = onDutyService.list(new LambdaQueryWrapper<OnDuty>().eq(OnDuty::getProjectId,projectId));
        Map<Integer, List<OnDuty>> map = list.stream().collect(groupingBy(OnDuty::getPositionId));
        List<ProjectPersonInfoVo> resultList = new ArrayList<>();
        // map循环
        for (Map.Entry<Integer, List<OnDuty>> entry : map.entrySet()){
            Integer key = entry.getKey();
            Position position = positionService.getById(key);
            ProjectPersonInfoVo projectPersonInfoVo = new ProjectPersonInfoVo();
            projectPersonInfoVo.setPostName(position.getName());
            List<OnDuty> onDuties = entry.getValue();
            long count = onDuties.stream().filter(e -> e.getState() == 1).count();
            int size = onDuties.size();
            BigDecimal rate = BigDecimal.valueOf(count).divide(BigDecimal.valueOf(size), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
            projectPersonInfoVo.setRate(rate.toString());
            resultList.add(projectPersonInfoVo);
        }
        return R.ok(resultList);
    }
    @ApiOperation(value = "获取岗位下拉框信息",response = Position.class)
    @GetMapping("/getPositionList")
    public R<List<Position>> getPositionList() {
        List<Position> list = positionService.list(new LambdaQueryWrapper<Position>().eq(Position::getDeleted, false));
        return R.ok(list);
    }
    @ApiOperation(value = "获取计划下拉框信息",response = Plan.class)
    @GetMapping("/getPlanList")
    public R<List<Plan>> getPlanList() {
        List<Plan> list = planService.list(new LambdaQueryWrapper<Plan>().eq(Plan::getDeleted, false));
        return R.ok(list);
    }
    @ApiOperation(value = "获取人员在岗列表",response = ProjectPersonOnDutyListVo.class)
    @PostMapping("/getProjectOnDutyList")
    public R<Page<ProjectPersonOnDutyListVo>> getProjectOnDutyList(@RequestBody @Valid ProjectPersonListQuery query) {
        Page<ProjectPersonOnDutyListVo> page = new Page<>(query.getPageNum(), query.getPageSize());
        List<ProjectPersonOnDutyListVo> list = onDutyService.getProjectOnDutyList(page,query);
        page.setRecords(list);
        return R.ok(page);
    }
    @ApiOperation(value = "获取人员在岗详情")
    @GetMapping("/getProjectOnDutyDetail/{id}")
    public R<?> getProjectOnDutyDetail(@PathVariable Integer id) {
        ProjectPersonOnDutyListVo vo = onDutyService.getProjectOnDutyDetail(id);
        return R.ok(vo);
    }
    @ApiOperation(value = "获取项目大屏最新重大风险源",response = ProjectInfo.class)
    @GetMapping("/getProjectDangerousSource")
    public R<ProjectInfo> getProjectDangerousSource(@RequestParam Integer projectId) {
        ProjectInfo projectInfo = projectInfoService.getOne(new LambdaQueryWrapper<ProjectInfo>().eq(ProjectInfo::getProjectId,projectId).eq(ProjectInfo::getDeleted, false).orderByDesc(ProjectInfo::getCreateTime).last("limit 1"));
        return R.ok(projectInfo);
    }
    @ApiOperation(value = "获取项目重大风险源列表")
    @PostMapping("/getProjectDangerousSourceList")
    public R<Page<ProjectInfo>> getProjectDangerousSourceList(@RequestBody @Valid ProjectDangerousSourceListQuery query) {
        Page<ProjectInfo> page = new Page<>(query.getPageNum(), query.getPageSize());
        LambdaQueryWrapper<ProjectInfo> wrapper = new LambdaQueryWrapper<ProjectInfo>().eq(ProjectInfo::getProjectId, query.getProjectId()).eq(ProjectInfo::getDeleted, false);
        if(query.getStartTime()!=null && !query.getStartTime().isEmpty()){
            wrapper.ge(ProjectInfo::getCreateTime, query.getStartTime());
        }
        if(query.getEndTime()!=null && !query.getEndTime().isEmpty()){
            wrapper.le(ProjectInfo::getCreateTime, query.getEndTime());
        }
        if(query.getContent()!=null && !query.getContent().isEmpty()){
            wrapper.like(ProjectInfo::getDetail, query.getContent());
        }
        Page<ProjectInfo> list = projectInfoService.page(page,wrapper);
        return R.ok(list);
    }
    @ApiOperation(value = "获取项目重大风险源详情")
    @GetMapping("/getProjectDangerousSourceDetail/{id}")
    public R<?> getProjectDangerousSourceDetail(@PathVariable Integer id) {
        ProjectInfo projectInfo = projectInfoService.getById(id);
        return R.ok(projectInfo);
    }
    @ApiOperation(value = "设备类型")
    @GetMapping("/deviceTypes")
    public R<?> deviceTypeOptions(@RequestParam(value = "title", required = false) String title) {
        return R.ok(SelectOptionVo.buildOptions(title, DeviceType.values()));
    }
    @ApiOperation(value = "各分项隐患趋势")
    @GetMapping("/getProjectHiddenDangerTrend")
    public R<List<ProjectHiddenDangerTrendVo>> getProjectHiddenDangerTrend(@RequestParam Integer projectId,@RequestParam(value = "desc", required = true) Boolean desc,@RequestParam(value = "type", required = true)Integer type) {
        List<ProjectHiddenDangerTrendVo> list = projectInfoService.getProjectHiddenDangerTrend(projectId);
        if(type==1){
            if(desc){
                list = list.stream().sorted(Comparator.comparingInt(ProjectHiddenDangerTrendVo::getThisMonth).reversed()).toList();
            }else {
                list = list.stream().sorted(Comparator.comparingInt(ProjectHiddenDangerTrendVo::getThisMonth)).toList();
            }
        }else {
            if(desc){
                list = list.stream().sorted(Comparator.comparingDouble(ProjectHiddenDangerTrendVo::getRate).reversed()).toList();
            }else {
                list = list.stream().sorted(Comparator.comparingDouble(ProjectHiddenDangerTrendVo::getRate)).toList();
            }
        }
        return R.ok(list);
    }
    @ApiOperation(value = "各分项隐患趋势列表")
    @PostMapping("/getProjectHiddenDangerTrendList")
    public R<List<ProjectHiddenDangerList>> getProjectHiddenDangerTrendList(@RequestBody @Valid ProjectHiddenDangerTrendListQuery query) {
        List<ProjectHiddenDangerList> list = projectInfoService.getProjectHiddenDangerTrendList(query);
        return  R.ok(list);
    }
    @ApiOperation(value = "大屏风险趋势")
    @PostMapping("/getProjectDangerousTrend")
    public R<List<ProjectDangerousTrendVo>> getProjectDangerousTrend(@RequestBody @Valid ProjectDangerousTrendQuery query) {
        List<ProjectDangerousTrendVo> list = projectInfoService.getProjectDangerousTrend(query);
        return R.ok(list);
    }
    @ApiOperation(value = "获取项目列表")
    @GetMapping("/list")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "clientId", value = "委托方ID", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "projectName", value = "项目名称", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "startDate", value = "开始日期", dataType = "date", paramType = "query"),
            @ApiImplicitParam(name = "endDate", value = "结束日期", dataType = "date", paramType = "query"),
            @ApiImplicitParam(name = "projectCategory", value = "项目类型 ongoing-在建工程,fixed-固定资产 ", dataType = "string", paramType = "query")
    })
    public R<List<Project>> getList(@RequestParam("clientId") Integer clientId, String projectName,
                                    @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
                                    @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
                                    @RequestParam("projectCategory") String projectCategory) {
        LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<Project>().eq(Project::getDeleted, false);
        if (clientId != null) {
            queryWrapper.eq(Project::getClientId, clientId);
        }
        if (projectName != null && !projectName.isEmpty()) {
            queryWrapper.like(Project::getName, projectName);
        }
        if (Objects.isNull(startDate)) {
            // 获取本月日期
            Date date = new Date();
            startDate = DateUtil.beginOfMonth(date);
        }
        Date finalStartDate = startDate;
        queryWrapper.and(wrapper -> wrapper
                .eq(Project::getStatus, 1)  // 在建项目
                .or(w -> w
                        .eq(Project::getStatus, 2)  // 已完成项目
                        .ge(Project::getSuccessTime, finalStartDate)  // 完成时间 >= 开始日期// 完成时间 <= 结束日期
                ));
        if ("ongoing".equals(projectCategory)) {
            queryWrapper.ne(Project::getType, 2);
        } else if ("fixed".equals(projectCategory)) {
            queryWrapper.eq(Project::getType, 2);
        }
        List<Project> list = projectService.list(queryWrapper);
        return R.ok(list);
    }
    @Resource
    UserFileService userFileService;
    @SneakyThrows
    @ApiOperation(value = "下载文件(名称)")
    @GetMapping("/download/{name}")
    public ResponseEntity<org.springframework.core.io.Resource> downloadFileByName(@PathVariable String name) {
        var userFile = userFileService.getOne(new LambdaQueryWrapper<UserFile>().eq(UserFile::getName, name));
        return downloadFile(userFile);
    }
    private ResponseEntity<org.springframework.core.io.Resource> downloadFile(UserFile userFile) throws IOException {
        InputStreamResource resource =resolveResource(userFile);
        var fileSize = userFile.getSize();
//        if(resource == null) {
//            resource = new InputStreamResource(getClass().getClassLoader().getResourceAsStream("images/wukong.png"));
//            fileSize = 6215360L;// resource.contentLength();
//        }
        String encodedFileName = URLEncoder.encode(userFile.getOriginFileName(), "UTF-8");
        String headerValue = String.format("attachment; filename=\"%s\"", encodedFileName);
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(userFile.getContentType()))
                .contentLength(fileSize)
                .header(HttpHeaders.CONTENT_DISPOSITION, headerValue)
                .body(resource);
    }
    public InputStreamResource resolveResource(UserFile userFile) throws IOException {
        var filePath = fileLocation.resolve(userFile.getName() + "." + userFile.getExtension()).normalize();
        if(!Files.exists(filePath)){
            return null;
        }
        return new InputStreamResource(Files.newInputStream(filePath));
    }
    private Path fileLocation;
    @Value("${file.upload.dir}/files")
    private String UPLOAD_DIR;
    @PostConstruct
    void init(){
        fileLocation  = Path.of(UPLOAD_DIR).toAbsolutePath().normalize();
        try {
            Files.createDirectories(this.fileLocation);
        } catch (Exception ex) {
            throw new RuntimeException("Could not create the directory where the uploaded files will be stored.", ex);
        }
    }
}