修改部分bug

This commit is contained in:
tangcy 2026-04-07 17:23:46 +08:00
parent dd99b2e2ff
commit e78bd59a1a
31 changed files with 710 additions and 153 deletions

View File

@ -143,12 +143,13 @@ public class WorkTicketController extends BaseController {
@Log(title = "工作票审批", businessType = BusinessType.UPDATE)
@PutMapping("/approve/{ticketId}")
public AjaxResult approve(@Parameter(description = "工作票 ID") @PathVariable("ticketId") Long ticketId,
@Parameter(description = "审核意见") @RequestParam(required = false) String reviewComment,
@Parameter(description = "施工作业必要性0 不必要 1 必要") @RequestParam(required = false) String reviewNecessity,
@Parameter(description = "施工作业可行性0 不可行 1 可行") @RequestParam(required = false) String reviewFeasibility,
@Parameter(description = "票证内容完整性JSON 数组)") @RequestParam(required = false) String reviewCompleteness,
@Parameter(description = "施工条件确认0 不符合 1 符合") @RequestParam(required = false) String reviewCondition) {
return toAjax(workTicketService.approveWorkTicket(ticketId, reviewComment, reviewNecessity, reviewFeasibility, reviewCompleteness, reviewCondition));
@Parameter(description = "审核意见") @RequestParam(required = false) String reviewComment,
@Parameter(description = "审批后状态2已签发默认") @RequestParam(required = false, defaultValue = "2") String status,
@Parameter(description = "施工作业必要性0 不必要 1 必要") @RequestParam(required = false) String reviewNecessity,
@Parameter(description = "施工作业可行性0 不可行 1 可行") @RequestParam(required = false) String reviewFeasibility,
@Parameter(description = "票证内容完整性JSON 数组)") @RequestParam(required = false) String reviewCompleteness,
@Parameter(description = "施工条件确认0 不符合 1 符合") @RequestParam(required = false) String reviewCondition) {
return toAjax(workTicketService.approveWorkTicket(ticketId, reviewComment, status, reviewNecessity, reviewFeasibility, reviewCompleteness, reviewCondition));
}
/**

View File

@ -63,6 +63,9 @@ public class WorkPlan extends BaseEntity {
@Schema(description = "施工单位名称")
private String constructionUnitName;
@Schema(description = "项目所属部门全路径")
private String constructionUnitFullPath;
@Schema(description = "监理单位IDsys_deptdept_type=2")
private Long supervisionUnitId;
@ -75,7 +78,7 @@ public class WorkPlan extends BaseEntity {
@Schema(description = "风险等级")
private String riskLevel;
@Schema(description = "项目状态0草稿1已提交2进行中3已完成4已取消")
@Schema(description = "项目状态0草稿1已提交2进行中3已完成")
private String projectStatus;
@Schema(description = "实施状态0未实施1实施中2整改中3待完工确认")

View File

@ -3,6 +3,8 @@ package com.admin.contractor.mapper;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.system.api.domain.SysDept;
import java.util.List;
/**
* 部门表查询用于根据用户部门取施工单位名称等
*
@ -25,4 +27,12 @@ public interface SysDeptMapper {
* @return 部门信息不存在返回 null
*/
SysDept selectDeptById(@Param("deptId") Long deptId);
/**
* 根据部门ID列表批量查询部门基础信息用于名称和全路径组装
*
* @param deptIds 部门ID列表
* @return 部门信息列表
*/
List<SysDept> selectDeptListByIds(@Param("deptIds") List<Long> deptIds);
}

View File

@ -82,7 +82,7 @@ public interface IWorkTicketService {
* @param reviewComment 审核意见
* @return 结果
*/
int approveWorkTicket(Long ticketId, String reviewComment, String reviewNecessity, String reviewFeasibility, String reviewCompleteness, String reviewCondition);
int approveWorkTicket(Long ticketId, String reviewComment, String status, String reviewNecessity, String reviewFeasibility, String reviewCompleteness, String reviewCondition);
/**
* 审批工作票驳回

View File

@ -20,6 +20,7 @@ import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.admin.contractor.mapper.SysUserMapper;
import com.ruoyi.system.api.domain.SysDept;
import com.ruoyi.system.api.domain.SysUser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -29,10 +30,13 @@ import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 工作计划Service业务层处理
@ -159,6 +163,15 @@ public class WorkPlanServiceImpl implements IWorkPlanService {
*/
@Override
public List<WorkPlan> selectWorkPlanList(WorkPlan workPlan) {
if (workPlan.getConstructionUnitId() == null) {
Long currentUserId = SecurityUtils.getUserId();
if (currentUserId != null) {
SysUser currentUser = sysUserMapper.selectUserById(currentUserId);
if (currentUser != null && currentUser.getDeptId() != null) {
workPlan.setConstructionUnitId(currentUser.getDeptId());
}
}
}
List<WorkPlan> list = workPlanMapper.selectWorkPlanList(workPlan);
// 加载作业班成员信息草稿状态显示文字关联的工作票ID风险控制卡ID球机申领表ID
for (WorkPlan plan : list) {
@ -534,109 +547,118 @@ public class WorkPlanServiceImpl implements IWorkPlanService {
return list;
}
// 按项目ID聚合一个项目一条记录汇总普通工作票状态和危险工作票状态
Map<Long, List<WorkPlan>> groupByProject = new LinkedHashMap<>();
for (WorkPlan wp : list) {
Long projectId = wp.getProjectId();
if (projectId == null) {
// projectId 为空的记录单独分组
groupByProject.computeIfAbsent(-1L, k -> new ArrayList<>()).add(wp);
} else {
groupByProject.computeIfAbsent(projectId, k -> new ArrayList<>()).add(wp);
// SQL 侧保留每项目最新票证查询Java 侧只做组织信息补齐避免 SQL 继续膨胀
enrichDepartmentInfo(list);
for (WorkPlan item : list) {
loadSysUsers(item);
}
return list;
}
private void enrichDepartmentInfo(List<WorkPlan> list) {
if (sysDeptMapper == null || list == null || list.isEmpty()) {
return;
}
// 第一步收集当前页需要的施工单位/监理单位部门ID
Set<Long> seedDeptIds = new HashSet<>();
for (WorkPlan item : list) {
if (item.getConstructionUnitId() != null) {
seedDeptIds.add(item.getConstructionUnitId());
}
if (item.getSupervisionUnitId() != null) {
seedDeptIds.add(item.getSupervisionUnitId());
}
}
if (seedDeptIds.isEmpty()) {
return;
}
// 第二步先批量查直接部门
Map<Long, SysDept> deptMap = new HashMap<>();
List<SysDept> directDepts = sysDeptMapper.selectDeptListByIds(new ArrayList<>(seedDeptIds));
for (SysDept dept : directDepts) {
deptMap.put(dept.getDeptId(), dept);
}
// 第三步根据 ancestors 收集全路径上的祖先部门ID再一次性补查
Set<Long> pathDeptIds = new HashSet<>(seedDeptIds);
for (SysDept dept : directDepts) {
pathDeptIds.addAll(parseAncestorIds(dept.getAncestors()));
}
Set<Long> toLoad = new HashSet<>(pathDeptIds);
toLoad.removeAll(deptMap.keySet());
if (!toLoad.isEmpty()) {
List<SysDept> ancestorDepts = sysDeptMapper.selectDeptListByIds(new ArrayList<>(toLoad));
for (SysDept dept : ancestorDepts) {
deptMap.put(dept.getDeptId(), dept);
}
}
List<WorkPlan> result = new ArrayList<>();
for (Map.Entry<Long, List<WorkPlan>> entry : groupByProject.entrySet()) {
List<WorkPlan> rows = entry.getValue();
if (rows.isEmpty()) {
// 第四步回填监理单位名称和施工单位全路径
for (WorkPlan item : list) {
fillSupervisionUnitName(item, deptMap);
fillConstructionUnitFullPath(item, deptMap);
}
}
private void fillSupervisionUnitName(WorkPlan item, Map<Long, SysDept> deptMap) {
if (item.getSupervisionUnitId() == null || StringUtils.isNotEmpty(item.getSupervisionUnitName())) {
return;
}
SysDept dept = deptMap.get(item.getSupervisionUnitId());
if (dept != null) {
item.setSupervisionUnitName(dept.getDeptName());
}
}
private void fillConstructionUnitFullPath(WorkPlan item, Map<Long, SysDept> deptMap) {
if (item.getConstructionUnitId() == null) {
return;
}
SysDept currentDept = deptMap.get(item.getConstructionUnitId());
if (currentDept == null) {
return;
}
// ancestors 格式一般为 "0,100,101"这里按顺序拼接成 "集团/事业部/部门"
List<Long> orderedDeptIds = new ArrayList<>(parseAncestorIds(currentDept.getAncestors()));
orderedDeptIds.add(currentDept.getDeptId());
List<String> names = new ArrayList<>();
for (Long deptId : orderedDeptIds) {
SysDept dept = deptMap.get(deptId);
if (dept != null && StringUtils.isNotEmpty(dept.getDeptName())) {
names.add(dept.getDeptName());
}
}
if (!names.isEmpty()) {
item.setConstructionUnitFullPath(String.join("/", names));
}
}
private List<Long> parseAncestorIds(String ancestors) {
if (StringUtils.isEmpty(ancestors)) {
return Collections.emptyList();
}
List<Long> ids = new ArrayList<>();
String[] parts = ancestors.split(",");
for (String part : parts) {
if (StringUtils.isEmpty(part)) {
continue;
}
WorkPlan first = rows.get(0);
WorkPlan agg = new WorkPlan();
// 复制项目本身的基础信息
agg.setProjectId(first.getProjectId());
agg.setProjectCode(first.getProjectCode());
agg.setProjectName(first.getProjectName());
agg.setWorkLocation(first.getWorkLocation());
agg.setWorkLocationDetail(first.getWorkLocationDetail());
agg.setLongitude(first.getLongitude());
agg.setLatitude(first.getLatitude());
agg.setWorkStartTime(first.getWorkStartTime());
agg.setWorkEndTime(first.getWorkEndTime());
agg.setSupervisorId(first.getSupervisorId());
agg.setSupervisorName(first.getSupervisorName());
agg.setSupervisorPosition(first.getSupervisorPosition());
agg.setSysUsers(first.getSysUsers());
agg.setConstructionUnitId(first.getConstructionUnitId());
agg.setConstructionUnitName(first.getConstructionUnitName());
agg.setSupervisionUnitId(first.getSupervisionUnitId());
agg.setSupervisionUnitName(first.getSupervisionUnitName());
agg.setWorkType(first.getWorkType());
agg.setRiskLevel(first.getRiskLevel());
agg.setProjectStatus(first.getProjectStatus());
agg.setImplementationStatus(first.getImplementationStatus());
agg.setApprovalStatus(first.getApprovalStatus());
agg.setApprover(first.getApprover());
agg.setApprovalTime(first.getApprovalTime());
agg.setApprovalComment(first.getApprovalComment());
agg.setCurrentProgress(first.getCurrentProgress());
agg.setDelFlag(first.getDelFlag());
agg.setRemark(first.getRemark());
agg.setCreateBy(first.getCreateBy());
agg.setCreateTime(first.getCreateTime());
agg.setUpdateBy(first.getUpdateBy());
agg.setUpdateTime(first.getUpdateTime());
// 现场完工复核相关字段
agg.setCompletionReviewResult(first.getCompletionReviewResult());
agg.setCompletionReviewPhotos(first.getCompletionReviewPhotos());
agg.setCompletionReviewBy(first.getCompletionReviewBy());
agg.setCompletionReviewTime(first.getCompletionReviewTime());
agg.setCompletionReviewRemark(first.getCompletionReviewRemark());
// 票证与出入证信息汇总直接取第一条记录的状态SQL 已分别查询普通工作票和危险作业票
String normalTicketStatus = null;
String hazardousTicketStatus = null;
String issuer = null;
String accessPermitNumber = null;
String accessPermitValidity = null;
String accessPermitStatus = null;
for (WorkPlan row : rows) {
// 普通工作票状态SQL 已过滤 ticket_type != '危险作业票'
if (normalTicketStatus == null && row.getWorkTicketStatus() != null) {
normalTicketStatus = row.getWorkTicketStatus();
}
// 危险作业票状态SQL 已过滤 ticket_type = '危险作业票'
if (hazardousTicketStatus == null && row.getHazardousWorkTicketStatus() != null) {
hazardousTicketStatus = row.getHazardousWorkTicketStatus();
}
// 签发人从普通工作票获取
if (issuer == null && row.getIssuer() != null) {
issuer = row.getIssuer();
}
// 出入证信息
if (accessPermitNumber == null && row.getAccessPermitNumber() != null) {
accessPermitNumber = row.getAccessPermitNumber();
accessPermitValidity = row.getAccessPermitValidity();
accessPermitStatus = row.getAccessPermitStatus();
}
String trimmed = part.trim();
if ("0".equals(trimmed)) {
continue;
}
try {
ids.add(Long.valueOf(trimmed));
} catch (NumberFormatException ignored) {
// ignore illegal ancestor id
}
agg.setWorkTicketStatus(normalTicketStatus);
agg.setHazardousWorkTicketStatus(hazardousTicketStatus);
agg.setIssuer(issuer);
agg.setAccessPermitNumber(accessPermitNumber);
agg.setAccessPermitValidity(accessPermitValidity);
agg.setAccessPermitStatus(accessPermitStatus);
// 关联的草稿状态文字与作业班成员信息
loadSysUsers(agg);
result.add(agg);
}
return result;
return ids;
}
/**

View File

@ -237,7 +237,7 @@ public class WorkTicketServiceImpl implements IWorkTicketService {
*/
@Override
@Transactional
public int approveWorkTicket(Long ticketId, String reviewComment, String reviewNecessity, String reviewFeasibility, String reviewCompleteness, String reviewCondition) {
public int approveWorkTicket(Long ticketId, String reviewComment, String status, String reviewNecessity, String reviewFeasibility, String reviewCompleteness, String reviewCondition) {
WorkTicket ticket = workTicketMapper.selectWorkTicketById(ticketId);
if (ticket == null) {
throw new ServiceException("工作票申请不存在");
@ -260,9 +260,14 @@ public class WorkTicketServiceImpl implements IWorkTicketService {
}
}
String reviewer = SecurityUtils.getUsername();
// 默认审批通过后置为已签发
if (StringUtils.isEmpty(status)) {
status = "2";
}
// 更新状态为已签发并保存审核确认信息
WorkTicket updateTicket = new WorkTicket();
updateTicket.setTicketId(ticketId);
updateTicket.setStatus(status);
updateTicket.setReviewer(reviewer);
updateTicket.setReviewTime(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
updateTicket.setReviewComment(reviewComment);

View File

@ -3,6 +3,7 @@ package com.admin.owner.controller;
import com.admin.owner.domain.OwnerAccessAuditEvent;
import com.admin.owner.domain.OwnerAccessAuditIssue;
import com.admin.owner.domain.OwnerAccessAuditItem;
import com.admin.owner.domain.vo.OwnerAccessAuditFileVO;
import com.admin.owner.service.IOwnerAccessAuditService;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
@ -13,9 +14,18 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@Tag(name = "准入事件审计(业主端)")
@ -40,6 +50,23 @@ public class OwnerAccessAuditController extends BaseController {
return success(ownerAccessAuditService.detail(eventId));
}
@Operation(summary = "查询附件展示列表(主表附件+分组材料)")
@GetMapping("/{eventId}/files")
public AjaxResult files(@Parameter(description = "事件ID") @PathVariable Long eventId) {
List<OwnerAccessAuditFileVO> list = ownerAccessAuditService.listFiles(eventId);
return success(list);
}
@Operation(summary = "附件打包下载")
@GetMapping("/{eventId}/files/download")
public void downloadFilesZip(
@Parameter(description = "事件ID") @PathVariable Long eventId,
HttpServletRequest request,
HttpServletResponse response
) throws Exception {
ownerAccessAuditService.downloadFilesZip(eventId, request, response);
}
@Operation(summary = "创建准入事件审计(仅初始化事件与默认检查项;提交请优先使用 POST /submit")
@Log(title = "准入事件审计", businessType = BusinessType.INSERT)
@PostMapping
@ -48,7 +75,7 @@ public class OwnerAccessAuditController extends BaseController {
return success(id);
}
@Operation(summary = "一步提交全部表单(基础信息+检查项+问题单+结论)。无 eventId 时先创建事件并落默认检查项再保存issues 传 [] 可清空问题;不传 issues 则不改动原有问题")
@Operation(summary = "一步提交全部表单(基础信息+检查项+问题单+结论)")
@Log(title = "准入事件审计-一步提交", businessType = BusinessType.UPDATE)
@PostMapping("/submit")
public AjaxResult submitAll(@Validated @RequestBody OwnerAccessAuditEvent event) {
@ -56,39 +83,38 @@ public class OwnerAccessAuditController extends BaseController {
return success(eventId);
}
@Operation(summary = "更新基础信息(分步接口,建议改用 POST /submit")
@Operation(summary = "更新基础信息")
@Log(title = "准入事件审计", businessType = BusinessType.UPDATE)
@PutMapping("/base")
public AjaxResult updateBase(@Validated @RequestBody OwnerAccessAuditEvent event) {
return toAjax(ownerAccessAuditService.updateBaseInfo(event));
}
@Operation(summary = "更新检查项(分步接口,建议改用 POST /submit")
@Operation(summary = "更新检查项")
@Log(title = "准入事件审计-检查项", businessType = BusinessType.UPDATE)
@PutMapping("/item")
public AjaxResult updateItem(@Validated @RequestBody OwnerAccessAuditItem item) {
return toAjax(ownerAccessAuditService.updateItem(item));
}
@Operation(summary = "批量更新检查项(分步接口,建议改用 POST /submit")
@Operation(summary = "批量更新检查项")
@Log(title = "准入事件审计-检查项", businessType = BusinessType.UPDATE)
@PutMapping("/items")
public AjaxResult updateItems(@Validated @RequestBody List<OwnerAccessAuditItem> items) {
return toAjax(ownerAccessAuditService.updateItems(items));
}
@Operation(summary = "新增问题单(分步接口,建议改用 POST /submit")
@Operation(summary = "新增问题单")
@Log(title = "准入事件审计-问题单", businessType = BusinessType.INSERT)
@PostMapping("/issue")
public AjaxResult addIssue(@Validated @RequestBody OwnerAccessAuditIssue issue) {
return toAjax(ownerAccessAuditService.addIssue(issue));
}
@Operation(summary = "删除问题单(分步接口,建议改用 POST /submit 整单替换 issues")
@Operation(summary = "删除问题单")
@Log(title = "准入事件审计-问题单", businessType = BusinessType.DELETE)
@DeleteMapping("/issue/{issueId}")
public AjaxResult deleteIssue(@PathVariable Long issueId) {
return toAjax(ownerAccessAuditService.deleteIssue(issueId));
}
}

View File

@ -70,6 +70,9 @@ public class OwnerAccessAuditEvent extends BaseEntity {
@Schema(description = "附件URL多个用逗号分隔")
private String attachmentUrls;
@Schema(description = "主表与关联表合计文件数量")
private Integer totalFileCount;
private String delFlag;
@Schema(description = "检查项列表(详情返回用)")
@ -78,4 +81,3 @@ public class OwnerAccessAuditEvent extends BaseEntity {
@Schema(description = "问题列表(详情返回用)")
private List<OwnerAccessAuditIssue> issues;
}

View File

@ -0,0 +1,27 @@
package com.admin.owner.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "准入审计附件展示对象")
public class OwnerAccessAuditFileVO {
@Schema(description = "文件URL")
private String fileUrl;
@Schema(description = "展示类型(图片/视频/文档/其他)")
private String displayType;
@Schema(description = "文件名")
private String fileName;
@Schema(description = "分类")
private String category;
@Schema(description = "上传时间")
private String uploadTime;
@Schema(description = "文件大小")
private String fileSize;
}

View File

@ -21,6 +21,8 @@ public interface OwnerAccessAuditMapper {
List<OwnerAccessAuditItem> selectItemsByEventId(@Param("eventId") Long eventId);
List<OwnerAccessAuditItem> selectItemsByEventIds(@Param("eventIds") List<Long> eventIds);
int insertItemsBatch(@Param("list") List<OwnerAccessAuditItem> list);
int updateItem(OwnerAccessAuditItem item);

View File

@ -3,7 +3,10 @@ package com.admin.owner.service;
import com.admin.owner.domain.OwnerAccessAuditEvent;
import com.admin.owner.domain.OwnerAccessAuditIssue;
import com.admin.owner.domain.OwnerAccessAuditItem;
import com.admin.owner.domain.vo.OwnerAccessAuditFileVO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
public interface IOwnerAccessAuditService {
@ -36,5 +39,22 @@ public interface IOwnerAccessAuditService {
* @return 事件ID
*/
Long submitAll(OwnerAccessAuditEvent event);
/**
* 查询附件展示列表主表附件 + 子表材料附件
*
* @param eventId 事件ID
* @return 附件展示列表
*/
List<OwnerAccessAuditFileVO> listFiles(Long eventId);
/**
* 根据事件ID下载附件压缩包
*
* @param eventId 事件ID
* @param request 请求对象
* @param response 响应对象
*/
void downloadFilesZip(Long eventId, HttpServletRequest request, HttpServletResponse response) throws Exception;
}

View File

@ -3,23 +3,38 @@ package com.admin.owner.service.impl;
import com.admin.owner.domain.OwnerAccessAuditEvent;
import com.admin.owner.domain.OwnerAccessAuditIssue;
import com.admin.owner.domain.OwnerAccessAuditItem;
import com.admin.owner.domain.vo.OwnerAccessAuditFileVO;
import com.admin.owner.mapper.OwnerAccessAuditMapper;
import com.admin.owner.service.IOwnerAccessAuditService;
import com.admin.contractor.mapper.SysDeptMapper;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.file.FileUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysDept;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Service
public class OwnerAccessAuditServiceImpl implements IOwnerAccessAuditService {
@ -30,9 +45,22 @@ public class OwnerAccessAuditServiceImpl implements IOwnerAccessAuditService {
@Resource
private SysDeptMapper sysDeptMapper;
private static final String CATEGORY_EVENT_ATTACHMENT = "审计事件附件";
private static final String CATEGORY_GROUP_1 = "准入过程";
private static final String CATEGORY_GROUP_2 = "检测与质量";
private static final String CATEGORY_GROUP_3 = "操作日志与合规";
private static final String CATEGORY_UNKNOWN = "其他";
private static final String DEFAULT_FILE_SIZE = "-";
private static final String DISPLAY_TYPE_IMAGE = "图片";
private static final String DISPLAY_TYPE_VIDEO = "视频";
private static final String DISPLAY_TYPE_DOC = "文档";
private static final String DISPLAY_TYPE_OTHER = "其他";
@Override
public List<OwnerAccessAuditEvent> list(OwnerAccessAuditEvent query) {
return ownerAccessAuditMapper.selectEventList(query);
List<OwnerAccessAuditEvent> events = ownerAccessAuditMapper.selectEventList(query);
fillTotalFileCount(events);
return events;
}
@Override
@ -195,7 +223,12 @@ public class OwnerAccessAuditServiceImpl implements IOwnerAccessAuditService {
throw new ServiceException("事件信息不能为空");
}
Long eventId = event.getEventId();
List<OwnerAccessAuditItem> submitItems = event.getItems();
List<OwnerAccessAuditIssue> submitIssues = event.getIssues();
if (eventId == null) {
// 新建并提交时先只创建主记录避免 createEvent 与后续同步逻辑重复写入检查项/问题单
event.setItems(null);
event.setIssues(null);
eventId = createEvent(event);
} else {
OwnerAccessAuditEvent existing = ownerAccessAuditMapper.selectEventById(eventId);
@ -204,6 +237,8 @@ public class OwnerAccessAuditServiceImpl implements IOwnerAccessAuditService {
}
}
event.setEventId(eventId);
event.setItems(submitItems);
event.setIssues(submitIssues);
if (event.getItems() != null && !event.getItems().isEmpty()) {
syncItemsByEventId(eventId, event.getItems());
@ -232,6 +267,110 @@ public class OwnerAccessAuditServiceImpl implements IOwnerAccessAuditService {
return eventId;
}
@Override
public List<OwnerAccessAuditFileVO> listFiles(Long eventId) {
if (eventId == null) {
throw new ServiceException("事件ID不能为空");
}
OwnerAccessAuditEvent event = ownerAccessAuditMapper.selectEventById(eventId);
if (event == null) {
throw new ServiceException("事件不存在");
}
List<OwnerAccessAuditFileVO> result = new ArrayList<>();
appendFiles(
result,
null,
event.getAttachmentUrls(),
CATEGORY_EVENT_ATTACHMENT,
selectUploadTime(event.getUpdateTime(), event.getCreateTime())
);
List<OwnerAccessAuditItem> items = ownerAccessAuditMapper.selectItemsByEventId(eventId);
for (OwnerAccessAuditItem item : items) {
appendFiles(
result,
null,
item.getMaterialUrls(),
resolveItemCategory(item.getGroupCode()),
selectUploadTime(item.getUpdateTime(), item.getCreateTime())
);
}
return result;
}
@Override
public void downloadFilesZip(Long eventId, HttpServletRequest request, HttpServletResponse response) throws Exception {
List<OwnerAccessAuditFileVO> files = listFiles(eventId);
if (files == null || files.isEmpty()) {
throw new ServiceException("暂无可下载文件");
}
response.setContentType("application/zip");
FileUtils.setAttachmentResponseHeader(response, "owner_access_audit_" + eventId + ".zip");
Set<String> urlDedup = new HashSet<>();
Map<String, Integer> nameCounter = new HashMap<>();
StringBuilder failed = new StringBuilder();
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
byte[] buffer = new byte[8192];
for (OwnerAccessAuditFileVO file : files) {
if (file == null || StringUtils.isEmpty(file.getFileUrl())) {
continue;
}
if (!urlDedup.add(file.getFileUrl())) {
continue;
}
String targetUrl = normalizeFileUrl(file.getFileUrl(), request);
String entryName = uniqueEntryName(safeFileName(file.getFileName(), file.getFileUrl()), nameCounter);
HttpURLConnection conn = null;
try {
URL url = new URL(targetUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(3000);
conn.setReadTimeout(10000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if (code < 200 || code >= 300) {
failed.append(file.getFileUrl()).append(" -> HTTP ").append(code).append("\n");
continue;
}
try (InputStream in = conn.getInputStream()) {
zos.putNextEntry(new ZipEntry(entryName));
int len;
while ((len = in.read(buffer)) != -1) {
zos.write(buffer, 0, len);
}
zos.closeEntry();
}
} catch (Exception ex) {
failed.append(file.getFileUrl()).append(" -> ").append(ex.getMessage()).append("\n");
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
if (failed.length() > 0) {
byte[] bytes = failed.toString().getBytes(StandardCharsets.UTF_8);
try (InputStream in = new ByteArrayInputStream(bytes)) {
zos.putNextEntry(new ZipEntry("download_failed.txt"));
int len;
while ((len = in.read(buffer)) != -1) {
zos.write(buffer, 0, len);
}
zos.closeEntry();
}
}
}
}
/**
* 一步提交结论 1/2 => 通过(3)3/4 => 不通过(4)无结论 => 审核中(1)
*/
@ -292,8 +431,210 @@ public class OwnerAccessAuditServiceImpl implements IOwnerAccessAuditService {
}
}
private void appendFiles(
List<OwnerAccessAuditFileVO> target,
Set<String> dedupKeySet,
String rawUrls,
String category,
Date uploadTime
) {
if (StringUtils.isEmpty(rawUrls)) {
return;
}
String uploadTimeStr = formatDate(uploadTime);
for (String url : splitUrls(rawUrls)) {
if (dedupKeySet != null) {
String dedupKey = category + "|" + url;
if (!dedupKeySet.add(dedupKey)) {
continue;
}
}
OwnerAccessAuditFileVO row = new OwnerAccessAuditFileVO();
row.setFileUrl(url);
row.setFileName(extractFileName(url));
row.setDisplayType(resolveDisplayType(url));
row.setCategory(category);
row.setUploadTime(uploadTimeStr);
row.setFileSize(DEFAULT_FILE_SIZE);
target.add(row);
}
}
private void fillTotalFileCount(List<OwnerAccessAuditEvent> events) {
if (events == null || events.isEmpty()) {
return;
}
List<Long> eventIds = new ArrayList<>();
Map<Long, Integer> countByEventId = new HashMap<>();
for (OwnerAccessAuditEvent event : events) {
if (event.getEventId() == null) {
continue;
}
eventIds.add(event.getEventId());
countByEventId.put(event.getEventId(), countUrls(event.getAttachmentUrls()));
}
if (!eventIds.isEmpty()) {
List<OwnerAccessAuditItem> items = ownerAccessAuditMapper.selectItemsByEventIds(eventIds);
for (OwnerAccessAuditItem item : items) {
if (item.getEventId() == null) {
continue;
}
int current = countByEventId.containsKey(item.getEventId()) ? countByEventId.get(item.getEventId()) : 0;
countByEventId.put(item.getEventId(), current + countUrls(item.getMaterialUrls()));
}
}
for (OwnerAccessAuditEvent event : events) {
if (event.getEventId() == null) {
event.setTotalFileCount(0);
continue;
}
event.setTotalFileCount(countByEventId.getOrDefault(event.getEventId(), 0));
}
}
private int countUrls(String rawUrls) {
return splitUrls(rawUrls).size();
}
private List<String> splitUrls(String rawUrls) {
List<String> urls = new ArrayList<>();
if (StringUtils.isEmpty(rawUrls)) {
return urls;
}
String[] parts = rawUrls.split(",");
for (String part : parts) {
if (StringUtils.isEmpty(part)) {
continue;
}
String url = part.trim();
if (StringUtils.isNotEmpty(url)) {
urls.add(url);
}
}
return urls;
}
private String resolveItemCategory(String groupCode) {
if ("1".equals(groupCode)) {
return CATEGORY_GROUP_1;
}
if ("2".equals(groupCode)) {
return CATEGORY_GROUP_2;
}
if ("3".equals(groupCode)) {
return CATEGORY_GROUP_3;
}
return CATEGORY_UNKNOWN;
}
private Date selectUploadTime(Date updateTime, Date createTime) {
return updateTime != null ? updateTime : createTime;
}
private String formatDate(Date date) {
if (date == null) {
return "";
}
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
}
private String extractFileName(String url) {
if (StringUtils.isEmpty(url)) {
return "";
}
String raw = url;
int queryIndex = raw.indexOf('?');
if (queryIndex >= 0) {
raw = raw.substring(0, queryIndex);
}
int slashIndex = raw.lastIndexOf('/');
String name = slashIndex >= 0 ? raw.substring(slashIndex + 1) : raw;
if (StringUtils.isEmpty(name)) {
return raw;
}
try {
return URLDecoder.decode(name, StandardCharsets.UTF_8.name());
} catch (Exception ex) {
return name;
}
}
private String resolveDisplayType(String url) {
String fileName = extractFileName(url).toLowerCase();
if (fileName.endsWith(".jpg")
|| fileName.endsWith(".jpeg")
|| fileName.endsWith(".png")
|| fileName.endsWith(".gif")
|| fileName.endsWith(".bmp")
|| fileName.endsWith(".webp")) {
return DISPLAY_TYPE_IMAGE;
}
if (fileName.endsWith(".mp4")
|| fileName.endsWith(".avi")
|| fileName.endsWith(".mov")
|| fileName.endsWith(".wmv")
|| fileName.endsWith(".mkv")) {
return DISPLAY_TYPE_VIDEO;
}
if (fileName.endsWith(".pdf")
|| fileName.endsWith(".doc")
|| fileName.endsWith(".docx")
|| fileName.endsWith(".xls")
|| fileName.endsWith(".xlsx")
|| fileName.endsWith(".ppt")
|| fileName.endsWith(".pptx")
|| fileName.endsWith(".txt")
|| fileName.endsWith(".zip")
|| fileName.endsWith(".rar")
|| fileName.endsWith(".7z")) {
return DISPLAY_TYPE_DOC;
}
return DISPLAY_TYPE_OTHER;
}
private String normalizeFileUrl(String rawUrl, HttpServletRequest request) {
String url = rawUrl.trim();
if (url.startsWith("http://") || url.startsWith("https://")) {
return url;
}
String base = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
if (url.startsWith("/")) {
return base + url;
}
return base + "/" + url;
}
private String safeFileName(String fileName, String fallbackUrl) {
String name = fileName;
if (StringUtils.isEmpty(name)) {
int slash = fallbackUrl.lastIndexOf('/');
name = slash >= 0 ? fallbackUrl.substring(slash + 1) : fallbackUrl;
}
name = name.replace("\\", "_").replace("/", "_");
if (StringUtils.isEmpty(name)) {
return "file";
}
return name;
}
private String uniqueEntryName(String fileName, Map<String, Integer> nameCounter) {
String key = fileName.toLowerCase();
int count = nameCounter.getOrDefault(key, 0);
nameCounter.put(key, count + 1);
if (count == 0) {
return fileName;
}
int dot = fileName.lastIndexOf('.');
if (dot > 0) {
return fileName.substring(0, dot) + "_" + count + fileName.substring(dot);
}
return fileName + "_" + count;
}
private String generateEventNo() {
return "ZR" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
}
}

View File

@ -82,7 +82,7 @@ public class PcCameraLedgerController extends BaseController {
return toAjax(pcCameraLedgerService.deletePcCameraLedgerByCameraIds(cameraIds));
}
@Operation(summary = "球机台账-状态变更", description = "状态0闲置 1已分配 2待回收 3已入库")
@Operation(summary = "球机台账-状态变更", description = "状态0在库 1已分配 2待回收")
@Log(title = "球机台账-状态", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestParam("cameraId") Long cameraId,

View File

@ -22,8 +22,8 @@ public class PcCameraLedger extends BaseEntity {
@Schema(description = "型号")
private String model;
@Excel(name = "状态", readConverterExp = "0=在库,1=已分配,2=已回收待入库,3=已入库")
@Schema(description = "状态0在库 1已分配 2已回收待入库 3已入库")
@Excel(name = "状态", readConverterExp = "0=在库,1=已分配,2=已回收待入库")
@Schema(description = "状态0在库 1已分配 2已回收待入库")
private String status;
@Excel(name = "所属单位")

View File

@ -8,7 +8,5 @@ public interface PcCameraStatus {
String ALLOCATED = "1";
/** 台账 status2已回收待入库 */
String RETURNED_PENDING_INBOUND = "2";
/** 台账 status3已入库(等同在库,可按你业务区分) */
String INBOUNDED = "3";
}

View File

@ -39,7 +39,7 @@ public interface PcCameraAllocMapper {
/** 单条更新分配记录为入库通过填仓库等alloc_status=3, audit_status=1 */
int updateInboundApproveOne(PcCameraAlloc alloc);
/** 批量更新分配记录为入库驳回audit_status=2 */
/** 批量更新分配记录为入库驳回alloc_status回退为1audit_status=2 */
int updateInboundReject(@Param("allocIds") List<Long> allocIds, @Param("auditBy") String auditBy, @Param("auditRemark") String auditRemark);
/**
@ -51,4 +51,4 @@ public interface PcCameraAllocMapper {
* 根据摄像机编号查询当前使用该相机的项目ID已分配且未回收完成
*/
Long selectProjectIdByCameraNo(@Param("cameraNo") String cameraNo);
}
}

View File

@ -68,11 +68,7 @@ public class PcCameraBizServiceImpl implements IPcCameraBizService {
// 逐个乐观更新避免并发重复分配
for (Long cameraId : cameraIds) {
int ok0 = ledgerMapper.updateStatusIfMatch(cameraId, PcCameraStatus.IN_STOCK, PcCameraStatus.ALLOCATED);
int ok3 = 0;
if (ok0 == 0) {
ok3 = ledgerMapper.updateStatusIfMatch(cameraId, PcCameraStatus.INBOUNDED, PcCameraStatus.ALLOCATED);
}
if (ok0 == 0 && ok3 == 0) {
PcCameraLedger one = ledgerMapper.selectPcCameraLedgerByCameraId(cameraId);
throw new ServiceException("球机不可分配,编号=" + (one != null ? one.getCameraNo() : cameraId) + ",当前状态=" + (one != null ? one.getStatus() : "未知"));
}
@ -189,7 +185,7 @@ public class PcCameraBizServiceImpl implements IPcCameraBizService {
}
for (PcCameraAlloc a : allocs) {
int ok = ledgerMapper.updateStatusIfMatch(a.getCameraId(), PcCameraStatus.RETURNED_PENDING_INBOUND, PcCameraStatus.INBOUNDED);
int ok = ledgerMapper.updateStatusIfMatch(a.getCameraId(), PcCameraStatus.RETURNED_PENDING_INBOUND, PcCameraStatus.IN_STOCK);
if (ok == 0) {
PcCameraLedger one = ledgerMapper.selectPcCameraLedgerByCameraId(a.getCameraId());
throw new ServiceException("入库失败,球机状态不匹配,编号=" + (one != null ? one.getCameraNo() : a.getCameraId()));
@ -199,7 +195,11 @@ public class PcCameraBizServiceImpl implements IPcCameraBizService {
PcCameraLedger ledger = new PcCameraLedger();
ledger.setCameraId(a.getCameraId());
ledger.setCameraNo(existingLedger.getCameraNo());
ledger.setModel(existingLedger.getModel());
ledger.setStatus(existingLedger.getStatus());
ledger.setOwnerUnit(existingLedger.getOwnerUnit());
ledger.setWarehouse(dto.getWarehouse());
ledger.setRemark(existingLedger.getRemark());
ledger.setUpdateBy(username);
ledgerMapper.updatePcCameraLedger(ledger);
}
@ -207,7 +207,12 @@ public class PcCameraBizServiceImpl implements IPcCameraBizService {
return rows;
}
/** ④ 入库审核驳回:仅更新分配记录 audit_status=2单条审核 */
/**
* 入库审核驳回
* 1. 分配记录回退到已分配状态回到回收入库列表重新提交
* 2. 台账状态从待入库回滚到已分配与分配记录保持一致
* 3. 审核状态标记为驳回保留驳回意见
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int rejectInbound(PcCameraInboundAuditDTO dto) {
@ -222,6 +227,15 @@ public class PcCameraBizServiceImpl implements IPcCameraBizService {
}
}
return allocMapper.updateInboundReject(java.util.Collections.singletonList(dto.getAllocId()), username, dto.getAuditRemark());
// 审核驳回后退回到回收提交节点需要回滚台账状态
for (PcCameraAlloc a : allocs) {
int ok = ledgerMapper.updateStatusIfMatch(a.getCameraId(), PcCameraStatus.RETURNED_PENDING_INBOUND, PcCameraStatus.ALLOCATED);
if (ok == 0) {
PcCameraLedger one = ledgerMapper.selectPcCameraLedgerByCameraId(a.getCameraId());
throw new ServiceException("驳回失败,球机台账状态不匹配,编号=" + (one != null ? one.getCameraNo() : a.getCameraId()));
}
}
return allocMapper.updateInboundReject(Collections.singletonList(dto.getAllocId()), username, dto.getAuditRemark());
}
}

View File

@ -36,11 +36,21 @@
<select id="selectAccessPermitById" parameterType="Long" resultMap="AccessPermitResult">
select ap.permit_id, ap.permit_number, ap.project_id,
wp.project_code, wp.project_name,
d.dept_name as construction_unit_name,
wu.dept_name as work_unit_name,
wu.leader as work_unit_leader_name,
wu.phone as work_unit_phone,
wt.work_start_time, wt.work_end_time,
ap.work_location, ap.team_members, ap.validity_start_time, ap.validity_end_time,
ap.vehicle_info, ap.attachment_urls, ap.status, ap.issuer, ap.issue_time,
ap.del_flag, ap.remark, ap.create_by, ap.create_time, ap.update_by, ap.update_time
from access_permit ap
left join work_plan wp on wp.project_id = ap.project_id and wp.del_flag = '0'
left join sys_dept wu on wu.dept_id = wp.construction_unit_id and wu.del_flag = '0'
left join work_ticket wt on wt.project_id = ap.project_id and wt.del_flag = '0'
and wt.ticket_id = (select wt2.ticket_id from work_ticket wt2 where wt2.project_id = ap.project_id and wt2.del_flag = '0' order by wt2.create_time desc limit 1)
left join sys_user u on u.user_id = wt.supervisor_id and u.del_flag = '0'
left join sys_dept d on d.dept_id = u.dept_id and d.del_flag = '0'
where ap.permit_id = #{permitId} and ap.del_flag = '0'
</select>
@ -101,6 +111,7 @@
left join sys_user u on u.user_id = wt.supervisor_id and u.del_flag = '0'
left join sys_dept d on d.dept_id = u.dept_id and d.del_flag = '0'
where ap.del_flag = '0'
and wp.approval_status = '1'
<if test="projectName != null and projectName != ''">
and wp.project_name like concat('%', #{projectName}, '%')
</if>

View File

@ -144,6 +144,7 @@
a.return_time as returnTime,
a.return_photo_urls as returnPhotoUrls,
a.return_remark as returnRemark,
a.alloc_status as allocStatus,
a.audit_status as auditStatus,
l.camera_no as cameraNo,
l.model as model,
@ -155,6 +156,7 @@
left join pc_camera_risk p on p.application_id = a.application_id and p.del_flag='0'
left join work_plan wp on wp.project_id = p.project_id and wp.del_flag='0'
where a.del_flag='0'
and a.alloc_status != 1
<if test="auditStatus != null and auditStatus != ''">
and a.audit_status = #{auditStatus}
</if>
@ -207,6 +209,7 @@
<update id="updateInboundReject">
update pc_camera_alloc set
alloc_status = '1',
audit_status = '2',
audit_by = #{auditBy},
audit_time = now(),

View File

@ -66,7 +66,7 @@
<select id="selectAvailableCameraList" resultMap="PcCameraLedgerMap">
select * from pc_camera_ledger
where del_flag='0'
and status in ('0','3')
and status = '0'
<if test="cameraNo != null and cameraNo != ''">
and camera_no like concat('%', #{cameraNo}, '%')
</if>

View File

@ -127,6 +127,7 @@
left join sys_dept d on d.dept_id = u.dept_id and d.del_flag = '0'
left join work_ticket wt on wt.ticket_id = r.work_ticket_id and wt.del_flag = '0'
where r.del_flag = '0'
and wp.approval_status = '1'
<if test="projectId != null">
and r.project_id = #{projectId}
</if>

View File

@ -10,10 +10,28 @@
select
dept_id as deptId,
dept_name as deptName,
ancestors as ancestors,
dept_type as deptType,
del_flag as delFlag
from sys_dept
where dept_id = #{deptId} and (del_flag = '0' or del_flag is null)
limit 1
</select>
<select id="selectDeptListByIds" resultType="com.ruoyi.system.api.domain.SysDept">
select
dept_id as deptId,
dept_name as deptName,
ancestors as ancestors,
dept_type as deptType,
del_flag as delFlag
from sys_dept
where (del_flag = '0' or del_flag is null)
<if test="deptIds != null and deptIds.size() > 0">
and dept_id in
<foreach collection="deptIds" item="deptId" open="(" separator="," close=")">
#{deptId}
</foreach>
</if>
</select>
</mapper>

View File

@ -47,6 +47,7 @@
<result property="propertyReviewStatus" column="property_review_status" />
<result property="workPeriod" column="work_period" />
<result property="aiIssueCount" column="ai_issue_count" />
<result property="completionReviewResult" column="completion_review_result" />
</resultMap>
<select id="selectWorkPlanById" parameterType="Long" resultMap="WorkPlanResult">
@ -63,9 +64,15 @@
<if test="projectCode != null and projectCode != ''">
and project_code like concat('%', #{projectCode}, '%')
</if>
<if test="constructionUnitId != null">
and construction_unit_id = #{constructionUnitId}
</if>
<if test="constructionUnitName != null and constructionUnitName != ''">
and construction_unit_name like concat('%', #{constructionUnitName}, '%')
</if>
<if test="supervisorId != null and supervisorId != ''">
and supervisor_id = #{supervisorId}
</if>
<if test="supervisionUnitName != null and supervisionUnitName != ''">
and supervision_unit_name like concat('%', #{supervisionUnitName}, '%')
</if>
@ -206,9 +213,11 @@
wp.supervisor_id,
wp.supervisor_name,
wp.supervisor_position,
wp.team_members as sys_users,
wp.team_members,
wp.construction_unit_id,
wp.construction_unit_name,
wp.supervision_unit_id,
wp.supervision_unit_name,
wp.work_type,
wp.risk_level,
wp.project_status,
@ -217,6 +226,7 @@
wp.approver,
wp.approval_time,
wp.approval_comment,
wp.completion_review_result,
wp.current_progress,
wp.remark,
wp.del_flag,
@ -250,7 +260,7 @@
from access_permit
where del_flag = '0'
) ap on ap.project_id = wp.project_id and ap.rn = 1
where wp.del_flag = '0'
where wp.del_flag = '0' and wp.approval_status is not null
<if test="projectName != null and projectName != ''">
and (wp.project_name like concat('%', #{projectName}, '%') or wp.project_code like concat('%', #{projectName}, '%'))
</if>

View File

@ -107,6 +107,7 @@
left join sys_user u on u.user_id = wt.supervisor_id and u.del_flag = '0'
left join sys_dept d on d.dept_id = u.dept_id and d.del_flag = '0'
where wt.del_flag = '0'
and wp.approval_status = '1'
<if test="projectName != null and projectName != ''">
and wp.project_name like concat('%', #{projectName}, '%')
</if>

View File

@ -154,6 +154,18 @@
order by group_code, sort_order, item_id
</select>
<select id="selectItemsByEventIds" resultMap="OwnerAccessAuditItemResult">
select * from owner_access_audit_item
where del_flag = '0'
<if test="eventIds != null and eventIds.size() > 0">
and event_id in
<foreach collection="eventIds" item="eventId" open="(" separator="," close=")">
#{eventId}
</foreach>
</if>
order by event_id, group_code, sort_order, item_id
</select>
<insert id="insertItemsBatch">
insert into owner_access_audit_item(
event_id, group_code, item_name, score, compliance, problem_desc, material_urls, severity,

View File

@ -50,6 +50,7 @@ public class SysDeptController extends BaseController
@GetMapping("/list")
public TableDataInfo list(SysDept dept)
{
markSkipThirdPartyScore(dept);
// 如果没有指定审核状态默认只查询审核通过的部门
if (StringUtils.isEmpty(dept.getAuditStatus()))
{
@ -70,9 +71,11 @@ public class SysDeptController extends BaseController
@GetMapping("/audit/list")
public TableDataInfo auditList(SysDept dept)
{
markSkipThirdPartyScore(dept);
startPage();
List<SysDept> depts = deptService.selectDeptList(dept);
return getDataTable(depts);
List<SysDept> deptsWithHierarchy = deptService.buildDeptHierarchyList(depts);
return getDataTable(deptsWithHierarchy);
}
/**
@ -227,4 +230,14 @@ public class SysDeptController extends BaseController
return toAjax(deptService.changeDeptStatus(deptId, status));
}
private void markSkipThirdPartyScore(SysDept dept)
{
if (dept == null)
{
return;
}
// 部门列表默认不依赖第三方评分避免外部不可用导致接口超时/报错
dept.getParams().put("skipThirdPartyScore", true);
}
}

View File

@ -80,7 +80,6 @@ public class SysUserController extends BaseController
* 获取用户列表
*/
@Operation(summary = "获取用户列表")
@RequiresPermissions("system:user:list")
@GetMapping("/list")
public TableDataInfo list(SysUser user)
{
@ -91,7 +90,6 @@ public class SysUserController extends BaseController
@Operation(summary = "导出用户数据")
@Log(title = "用户管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:user:export")
@PostMapping("/export")
public void export(HttpServletResponse response, SysUser user)
{
@ -102,7 +100,6 @@ public class SysUserController extends BaseController
@Operation(summary = "导入用户数据")
@Log(title = "用户管理", businessType = BusinessType.IMPORT)
@RequiresPermissions("system:user:import")
@PostMapping("/importData")
public AjaxResult importData(@Parameter(description = "导入文件") MultipartFile file, @Parameter(description = "是否更新支持") boolean updateSupport) throws Exception
{
@ -230,7 +227,6 @@ public class SysUserController extends BaseController
* 根据用户编号获取详细信息
*/
@Operation(summary = "根据用户编号获取详细信息")
@RequiresPermissions("system:user:query")
@GetMapping(value = { "/", "/{userId}" })
public AjaxResult getInfo(@Parameter(description = "用户ID") @PathVariable(value = "userId", required = false) Long userId)
{
@ -256,7 +252,6 @@ public class SysUserController extends BaseController
* 新增用户
*/
@Operation(summary = "新增用户")
@RequiresPermissions("system:user:add")
@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysUser user)
@ -289,7 +284,6 @@ public class SysUserController extends BaseController
* 修改用户
*/
@Operation(summary = "修改用户")
@RequiresPermissions("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysUser user)
@ -323,7 +317,6 @@ public class SysUserController extends BaseController
* 删除用户
*/
@Operation(summary = "删除用户")
@RequiresPermissions("system:user:remove")
@Log(title = "用户管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{userIds}")
public AjaxResult remove(@Parameter(description = "用户ID数组") @PathVariable Long[] userIds)
@ -339,7 +332,6 @@ public class SysUserController extends BaseController
* 重置密码
*/
@Operation(summary = "重置用户密码")
@RequiresPermissions("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/resetPwd")
public AjaxResult resetPwd(@RequestBody SysUser user)
@ -355,7 +347,6 @@ public class SysUserController extends BaseController
* 状态修改
*/
@Operation(summary = "修改用户状态")
@RequiresPermissions("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody SysUser user)
@ -370,7 +361,6 @@ public class SysUserController extends BaseController
* 根据用户编号获取授权角色
*/
@Operation(summary = "根据用户编号获取授权角色")
@RequiresPermissions("system:user:query")
@GetMapping("/authRole/{userId}")
public AjaxResult authRole(@Parameter(description = "用户ID") @PathVariable("userId") Long userId)
{
@ -386,7 +376,6 @@ public class SysUserController extends BaseController
* 用户授权角色
*/
@Operation(summary = "用户授权角色")
@RequiresPermissions("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.GRANT)
@PutMapping("/authRole")
public AjaxResult insertAuthRole(@Parameter(description = "用户ID") Long userId, @Parameter(description = "角色ID数组") Long[] roleIds)
@ -401,7 +390,6 @@ public class SysUserController extends BaseController
* 获取部门树列表
*/
@Operation(summary = "获取部门树列表")
@RequiresPermissions("system:user:list")
@GetMapping("/deptTree")
public AjaxResult deptTree(SysDept dept)
{
@ -413,7 +401,6 @@ public class SysUserController extends BaseController
* status0正常 1停用 2待审核 3审核不通过审核通过传 0 1审核不通过传 3此时 auditOpinion 必填
*/
@Operation(summary = "审核用户", description = "请求体status0正常/1停用/3审核不通过status=3 时 auditOpinion 必填")
@RequiresPermissions("system:user:audit")
@Log(title = "用户审核", businessType = BusinessType.UPDATE)
@PutMapping("/audit/{userId}")
public AjaxResult audit(@Parameter(description = "用户ID") @PathVariable Long userId, @RequestBody java.util.Map<String, String> params)

View File

@ -54,6 +54,10 @@ public class SysDeptServiceImpl implements ISysDeptService
public List<SysDept> selectDeptList(SysDept dept)
{
List<SysDept> depts = deptMapper.selectDeptList(dept);
if (shouldSkipThirdPartyScore(dept))
{
return depts;
}
// 为每个部门获取企业评分只针对施工单位监理单位业主单位
if (thirdPartyService != null && depts != null && !depts.isEmpty()) {
ObjectMapper objectMapper = new ObjectMapper();
@ -126,10 +130,33 @@ public class SysDeptServiceImpl implements ISysDeptService
@Override
public List<TreeSelect> selectDeptTreeList(SysDept dept)
{
if (dept == null)
{
dept = new SysDept();
}
dept.getParams().put("skipThirdPartyScore", true);
List<SysDept> depts = SpringUtils.getAopProxy(this).selectDeptList(dept);
return buildDeptTreeSelect(depts);
}
private boolean shouldSkipThirdPartyScore(SysDept dept)
{
if (dept == null || dept.getParams() == null)
{
return false;
}
Object flag = dept.getParams().get("skipThirdPartyScore");
if (flag instanceof Boolean)
{
return (Boolean) flag;
}
if (flag instanceof String)
{
return Boolean.parseBoolean((String) flag);
}
return false;
}
/**
* 构建前端所需要树结构
*

View File

@ -72,7 +72,6 @@ public class SysUserServiceImpl implements ISysUserService
* @return 用户信息集合信息
*/
@Override
@DataScope(deptAlias = "d", userAlias = "u")
public List<SysUser> selectUserList(SysUser user)
{
return userMapper.selectUserList(user);
@ -85,7 +84,6 @@ public class SysUserServiceImpl implements ISysUserService
* @return 用户信息集合信息
*/
@Override
@DataScope(deptAlias = "d", userAlias = "u")
public List<SysUser> selectAllocatedList(SysUser user)
{
return userMapper.selectAllocatedList(user);
@ -98,7 +96,6 @@ public class SysUserServiceImpl implements ISysUserService
* @return 用户信息集合信息
*/
@Override
@DataScope(deptAlias = "d", userAlias = "u")
public List<SysUser> selectUnallocatedList(SysUser user)
{
return userMapper.selectUnallocatedList(user);

View File

@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
@ -21,12 +22,17 @@ import java.util.Collections;
public class ThirdPartyHttpClient {
private static final String BASE_URL = "http://1.13.245.108/trainCore";
private static final int CONNECT_TIMEOUT_MS = 1500;
private static final int READ_TIMEOUT_MS = 2500;
private static final ObjectMapper objectMapper = new ObjectMapper();
private RestTemplate restTemplate;
@PostConstruct
public void init() {
restTemplate = new RestTemplate();
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(CONNECT_TIMEOUT_MS);
factory.setReadTimeout(READ_TIMEOUT_MS);
restTemplate = new RestTemplate(factory);
}
/**

View File

@ -72,7 +72,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</if>
<!-- 数据范围过滤 -->
${params.dataScope}
order by d.parent_id, d.order_num
order by d.create_time desc, d.dept_id desc
</select>
<select id="selectDeptListByRoleId" resultType="Long">