@@ -6,7 +6,9 @@ import com.ningdatech.basic.model.PageVo; | |||||
import com.ningdatech.pmapi.filemanage.model.param.ProjectFileListParam; | import com.ningdatech.pmapi.filemanage.model.param.ProjectFileListParam; | ||||
import com.ningdatech.pmapi.filemanage.model.vo.ProjectFileListVO; | import com.ningdatech.pmapi.filemanage.model.vo.ProjectFileListVO; | ||||
import com.ningdatech.pmapi.filemanage.model.vo.ProjectFileVO; | import com.ningdatech.pmapi.filemanage.model.vo.ProjectFileVO; | ||||
import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | import com.ningdatech.pmapi.projectlib.model.entity.Project; | ||||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectDetailVO; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
@@ -29,6 +31,8 @@ public class ProjectFileManage { | |||||
private final IProjectService projectService; | private final IProjectService projectService; | ||||
private final ProjectLibManage projectLibManage; | |||||
public PageVo<ProjectFileListVO> list(ProjectFileListParam param) { | public PageVo<ProjectFileListVO> list(ProjectFileListParam param) { | ||||
Page<Project> page = param.page(); | Page<Project> page = param.page(); | ||||
projectService.page(page,Wrappers.lambdaQuery(Project.class) | projectService.page(page,Wrappers.lambdaQuery(Project.class) | ||||
@@ -52,6 +56,9 @@ public class ProjectFileManage { | |||||
} | } | ||||
public ProjectFileVO file(Long projectId) { | public ProjectFileVO file(Long projectId) { | ||||
ProjectDetailVO projectDetailVo = projectLibManage.getProjectDetail(projectId); | |||||
return null; | return null; | ||||
} | } | ||||
@@ -0,0 +1,50 @@ | |||||
package com.ningdatech.pmapi.projectdeclared.controller; | |||||
import com.ningdatech.basic.model.PageVo; | |||||
import com.ningdatech.pmapi.common.util.ExcelDownUtil; | |||||
import com.ningdatech.pmapi.projectdeclared.manage.DelayedApplyManage; | |||||
import com.ningdatech.pmapi.projectdeclared.model.dto.DelayedApplyDTO; | |||||
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | |||||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | |||||
import io.swagger.annotations.Api; | |||||
import io.swagger.annotations.ApiOperation; | |||||
import lombok.RequiredArgsConstructor; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.validation.annotation.Validated; | |||||
import org.springframework.web.bind.annotation.*; | |||||
import javax.servlet.http.HttpServletResponse; | |||||
/** | |||||
* @Classname DelayedProjectController | |||||
* @Description | |||||
* @Date 2023/6/7 18:50 | |||||
* @Author PoffyZhang | |||||
*/ | |||||
@Slf4j | |||||
@Validated | |||||
@RestController | |||||
@RequestMapping("/api/v1/declared/delayed") | |||||
@Api(value = "DelayedProjectController", tags = "申报管理-延期项目") | |||||
@RequiredArgsConstructor | |||||
public class DelayedApplyController { | |||||
private final DelayedApplyManage delayedApplyManage; | |||||
@ApiOperation(value = "过期的项目列表", notes = "过期的项目列表") | |||||
@GetMapping("/project-list") | |||||
public PageVo<ProjectLibListItemVO> projectlist(@ModelAttribute ProjectListReq req) { | |||||
return delayedApplyManage.projectLibList(req); | |||||
} | |||||
@GetMapping("/export") | |||||
@ApiOperation("过期的项目列表导出") | |||||
public void exportList(ProjectListReq req, HttpServletResponse response){ | |||||
ExcelDownUtil.downXls(response,req,delayedApplyManage::exportList); | |||||
} | |||||
@ApiOperation(value = "延期申报", notes = "延期申报") | |||||
@PostMapping("/apply") | |||||
public String delayedApply(@Validated @RequestBody DelayedApplyDTO dto) { | |||||
return delayedApplyManage.delayedApply(dto); | |||||
} | |||||
} |
@@ -316,6 +316,11 @@ public class DeclaredProjectManage { | |||||
} | } | ||||
if (Objects.isNull(draft.getId())) { | if (Objects.isNull(draft.getId())) { | ||||
draft.setCreateOn(LocalDateTime.now()); | draft.setCreateOn(LocalDateTime.now()); | ||||
}else{ | |||||
ProjectDraft old = projectDraftService.getById(draft.getId()); | |||||
if(Objects.isNull(old)){ | |||||
draft.setCreateOn(LocalDateTime.now()); | |||||
} | |||||
} | } | ||||
draft.setUpdateOn(LocalDateTime.now()); | draft.setUpdateOn(LocalDateTime.now()); | ||||
draft.setUserId(String.valueOf(userId)); | draft.setUserId(String.valueOf(userId)); | ||||
@@ -91,6 +91,7 @@ public class DefaultDeclaredProjectManage { | |||||
public void checkDuplication(ProjectDTO project){ | public void checkDuplication(ProjectDTO project){ | ||||
VUtils.isTrue(projectService.count(Wrappers.lambdaQuery(Project.class) | VUtils.isTrue(projectService.count(Wrappers.lambdaQuery(Project.class) | ||||
.eq(Project::getProjectName,project.getProjectName()) | .eq(Project::getProjectName,project.getProjectName()) | ||||
.eq(Project::getNewest,Boolean.TRUE) | |||||
.ne(Objects.nonNull(project.getProjectCode()),Project::getProjectCode,project.getProjectCode())) > 0) | .ne(Objects.nonNull(project.getProjectCode()),Project::getProjectCode,project.getProjectCode())) > 0) | ||||
.throwMessage(String.format("修改失败 此项目名 【%s】 已存在!",project.getProjectName())); | .throwMessage(String.format("修改失败 此项目名 【%s】 已存在!",project.getProjectName())); | ||||
} | } | ||||
@@ -0,0 +1,181 @@ | |||||
package com.ningdatech.pmapi.projectdeclared.manage; | |||||
import cn.hutool.core.bean.BeanUtil; | |||||
import cn.hutool.core.collection.CollUtil; | |||||
import com.alibaba.excel.EasyExcel; | |||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||||
import com.google.common.collect.Lists; | |||||
import com.ningdatech.basic.function.VUtils; | |||||
import com.ningdatech.basic.model.PageVo; | |||||
import com.ningdatech.basic.util.CollUtils; | |||||
import com.ningdatech.basic.util.NdDateUtils; | |||||
import com.ningdatech.pmapi.common.constant.BizConst; | |||||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | |||||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | |||||
import com.ningdatech.pmapi.common.util.ExcelDownUtil; | |||||
import com.ningdatech.pmapi.common.util.ExcelExportStyle; | |||||
import com.ningdatech.pmapi.projectdeclared.model.dto.DeclaredProjectExportDTO; | |||||
import com.ningdatech.pmapi.projectdeclared.model.dto.DelayedApplyDTO; | |||||
import com.ningdatech.pmapi.projectdeclared.model.entity.Contract; | |||||
import com.ningdatech.pmapi.projectdeclared.model.entity.PaymentPlan; | |||||
import com.ningdatech.pmapi.projectdeclared.model.entity.Purchase; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum; | |||||
import com.ningdatech.pmapi.projectlib.helper.ProjectHelper; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | |||||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | |||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||||
import lombok.RequiredArgsConstructor; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.springframework.beans.BeanUtils; | |||||
import org.springframework.stereotype.Component; | |||||
import javax.servlet.http.HttpServletResponse; | |||||
import java.io.IOException; | |||||
import java.time.LocalDateTime; | |||||
import java.util.List; | |||||
import java.util.Objects; | |||||
import java.util.concurrent.atomic.AtomicInteger; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* @Classname DelayedManage | |||||
* @Description | |||||
* @Date 2023/5/29 14:48 | |||||
* @Author PoffyZhang | |||||
*/ | |||||
@Component | |||||
@Slf4j | |||||
@RequiredArgsConstructor | |||||
public class DelayedApplyManage { | |||||
private final IProjectService projectService; | |||||
private final UserInfoHelper userInfoHelper; | |||||
private final StateMachineUtils stateMachineUtils; | |||||
/** | |||||
* 延期的-项目列表 | |||||
* @param req | |||||
* @return | |||||
*/ | |||||
public PageVo<ProjectLibListItemVO> projectLibList(ProjectListReq req) { | |||||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||||
VUtils.isTrue(Objects.isNull(user)).throwMessage("获取登录用户失败!"); | |||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | |||||
//待终验 并且已经过期 | |||||
query.eq(Project::getStatus,ProjectStatusEnum.TO_BE_FINALLY_INSPECTED.getCode()); | |||||
query.eq(Project::getStage,ProjectStatusEnum.PROJECT_APPROVED.getCode()); | |||||
query.lt(Project::getPlanAcceptanceTime, LocalDateTime.now()); | |||||
query.eq(Project::getNewest,Boolean.TRUE); | |||||
query.isNotNull(Project::getApprovalDate); | |||||
query.isNotNull(Project::getBuildCycle); | |||||
query.orderByAsc(Project::getApprovalDate); | |||||
Page<Project> page = projectService.page(req.page(), query); | |||||
long total; | |||||
if ((total = page.getTotal()) == 0) { | |||||
return PageVo.empty(); | |||||
} | |||||
List<ProjectLibListItemVO> records = CollUtils.convert(page.getRecords(), w -> { | |||||
ProjectLibListItemVO item = new ProjectLibListItemVO(); | |||||
item.setId(w.getId()); | |||||
item.setProjectName(w.getProjectName()); | |||||
item.setCreateOn(w.getCreateOn()); | |||||
item.setDeclaredAmount(w.getDeclareAmount()); | |||||
item.setStage(w.getStage()); | |||||
item.setStatus(w.getStatus()); | |||||
item.setProjectType(w.getProjectType()); | |||||
item.setProjectYear(w.getProjectYear()); | |||||
item.setBuildOrg(w.getBuildOrgName()); | |||||
item.setBizDomain(w.getBizDomain()); | |||||
item.setProcessStatus(w.getProcessStatus()); | |||||
item.setInstCode(w.getInstCode()); | |||||
item.setIsHigherSuperOrg(w.getIsHigherSuperOrg()); | |||||
item.setApprovedAmount(w.getApprovalAmount()); | |||||
item.setApprovalDate(w.getApprovalDate()); | |||||
item.setBuildCycle(StringUtils.isNotBlank(w.getBuildCycle()) ? | |||||
Integer.valueOf(w.getBuildCycle()) : null); | |||||
item.setPlanAcceptanceTime(w.getPlanAcceptanceTime()); | |||||
return item; | |||||
}); | |||||
return PageVo.of(records, total); | |||||
} | |||||
public void exportList(HttpServletResponse response, ProjectListReq param) { | |||||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||||
VUtils.isTrue(Objects.isNull(user)).throwMessage("获取登录用户失败!"); | |||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param); | |||||
//待终验 | |||||
query.eq(Project::getStatus,ProjectStatusEnum.TO_BE_FINALLY_INSPECTED.getCode()); | |||||
query.eq(Project::getStage,ProjectStatusEnum.PROJECT_APPROVED.getCode()); | |||||
query.eq(Project::getNewest,Boolean.TRUE); | |||||
query.isNotNull(Project::getApprovalDate); | |||||
query.isNotNull(Project::getBuildCycle); | |||||
query.orderByAsc(Project::getApprovalDate); | |||||
List<Project> records = projectService.list(query); | |||||
AtomicInteger serialNumber = new AtomicInteger(0); | |||||
List<DeclaredProjectExportDTO> collect = Lists.newArrayList(); | |||||
if(CollUtil.isNotEmpty(records)){ | |||||
collect = records.stream().map(r -> { | |||||
DeclaredProjectExportDTO exportDTO = new DeclaredProjectExportDTO(); | |||||
BeanUtils.copyProperties(r, exportDTO); | |||||
exportDTO.setProjectTypeName(ProjectTypeEnum.getDesc(r.getProjectType())); | |||||
exportDTO.setStatusName(ProjectStatusEnum.getDesc(r.getStatus())); | |||||
String createOnStr = NdDateUtils.format(r.getCreateOn(), "yyyy-MM-dd HH:mm"); | |||||
exportDTO.setCreateOn(createOnStr); | |||||
exportDTO.setSerialNumber(serialNumber.incrementAndGet()); | |||||
exportDTO.setPlanAcceptanceTime(Objects.nonNull(r.getPlanAcceptanceTime()) ? | |||||
NdDateUtils.format(r.getPlanAcceptanceTime(), "yyyy-MM-dd") : StringUtils.EMPTY); | |||||
return exportDTO; | |||||
}).collect(Collectors.toList()); | |||||
} | |||||
String fileName = "待终验申请项目列表"; | |||||
ExcelDownUtil.setFileName(fileName,response); | |||||
//数据导出处理函数 | |||||
try { | |||||
EasyExcel.write(response.getOutputStream(), DeclaredProjectExportDTO.class) | |||||
.autoCloseStream(false) | |||||
.registerWriteHandler(ExcelExportStyle.formalStyle()) | |||||
.sheet(fileName) | |||||
.doWrite(collect); | |||||
} catch (IOException e) { | |||||
throw new RuntimeException(e); | |||||
} catch (Exception e) { | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
/** | |||||
* 延期申请 | |||||
* @param dto | |||||
* @return | |||||
*/ | |||||
public String delayedApply(DelayedApplyDTO dto) { | |||||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||||
String employeeCode = user.getEmployeeCode(); | |||||
VUtils.isTrue(StringUtils.isBlank(employeeCode)).throwMessage("获取登录用户 员工号 失败!"); | |||||
Long projectId = dto.getProjectId(); | |||||
Project project = projectService.getNewProject(projectId); | |||||
VUtils.isTrue(Objects.isNull(project)).throwMessage("提交失败 此项目不存在!"); | |||||
//首先要判断 项目当前状态 是不是 以终验 | |||||
VUtils.isTrue(!ProjectStatusEnum.TO_BE_FINALLY_INSPECTED.getCode().equals(project.getStatus()) || | |||||
!ProjectStatusEnum.PROJECT_APPROVED.getCode().equals(project.getStage())) | |||||
.throwMessage("提交失败 该项目不是 已立项|待终验"); | |||||
VUtils.isTrue(Objects.isNull(project.getPlanAcceptanceTime()) | |||||
|| project.getPlanAcceptanceTime().compareTo(LocalDateTime.now()) <= 0) | |||||
.throwMessage("当前项目还未过期验收"); | |||||
return "申请发起成功"; | |||||
} | |||||
} |
@@ -46,6 +46,7 @@ import org.springframework.beans.BeanUtils; | |||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.time.LocalDateTime; | |||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
@@ -86,9 +87,10 @@ public class FinalAcceptanceManage { | |||||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | ||||
VUtils.isTrue(Objects.isNull(user)).throwMessage("获取登录用户失败!"); | VUtils.isTrue(Objects.isNull(user)).throwMessage("获取登录用户失败!"); | ||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req); | ||||
//待终验 | |||||
//待终验 并且还未过期 | |||||
query.eq(Project::getStatus,ProjectStatusEnum.TO_BE_FINALLY_INSPECTED.getCode()); | query.eq(Project::getStatus,ProjectStatusEnum.TO_BE_FINALLY_INSPECTED.getCode()); | ||||
query.eq(Project::getStage,ProjectStatusEnum.PROJECT_APPROVED.getCode()); | query.eq(Project::getStage,ProjectStatusEnum.PROJECT_APPROVED.getCode()); | ||||
query.ge(Project::getPlanAcceptanceTime, LocalDateTime.now()); | |||||
query.eq(Project::getNewest,Boolean.TRUE); | query.eq(Project::getNewest,Boolean.TRUE); | ||||
query.isNotNull(Project::getApprovalDate); | query.isNotNull(Project::getApprovalDate); | ||||
query.isNotNull(Project::getBuildCycle); | query.isNotNull(Project::getBuildCycle); | ||||
@@ -118,6 +120,7 @@ public class FinalAcceptanceManage { | |||||
item.setApprovalDate(w.getApprovalDate()); | item.setApprovalDate(w.getApprovalDate()); | ||||
item.setBuildCycle(StringUtils.isNotBlank(w.getBuildCycle()) ? | item.setBuildCycle(StringUtils.isNotBlank(w.getBuildCycle()) ? | ||||
Integer.valueOf(w.getBuildCycle()) : null); | Integer.valueOf(w.getBuildCycle()) : null); | ||||
item.setPlanAcceptanceTime(w.getPlanAcceptanceTime()); | |||||
return item; | return item; | ||||
}); | }); | ||||
return PageVo.of(records, total); | return PageVo.of(records, total); | ||||
@@ -147,7 +150,8 @@ public class FinalAcceptanceManage { | |||||
String createOnStr = NdDateUtils.format(r.getCreateOn(), "yyyy-MM-dd HH:mm"); | String createOnStr = NdDateUtils.format(r.getCreateOn(), "yyyy-MM-dd HH:mm"); | ||||
exportDTO.setCreateOn(createOnStr); | exportDTO.setCreateOn(createOnStr); | ||||
exportDTO.setSerialNumber(serialNumber.incrementAndGet()); | exportDTO.setSerialNumber(serialNumber.incrementAndGet()); | ||||
exportDTO.setPlanAcceptanceTime(convertPlanAcceptanceTime(r)); | |||||
exportDTO.setPlanAcceptanceTime(Objects.nonNull(r.getPlanAcceptanceTime()) ? | |||||
NdDateUtils.format(r.getPlanAcceptanceTime(), "yyyy-MM-dd") : StringUtils.EMPTY); | |||||
return exportDTO; | return exportDTO; | ||||
}).collect(Collectors.toList()); | }).collect(Collectors.toList()); | ||||
} | } | ||||
@@ -168,14 +172,6 @@ public class FinalAcceptanceManage { | |||||
} | } | ||||
} | } | ||||
private String convertPlanAcceptanceTime(Project project) { | |||||
if (Objects.nonNull(project.getApprovalDate()) && StringUtils.isNotBlank(project.getBuildCycle())) { | |||||
Integer buidCycle = Integer.valueOf(project.getBuildCycle()); | |||||
return NdDateUtils.format(project.getApprovalDate().plusMonths(buidCycle), "yyyy-MM-dd"); | |||||
} | |||||
return StringUtils.EMPTY; | |||||
} | |||||
public FinalAcceptanceVO detailByProjectId(Long projectId) { | public FinalAcceptanceVO detailByProjectId(Long projectId) { | ||||
FinalAcceptanceVO vo = new FinalAcceptanceVO(); | FinalAcceptanceVO vo = new FinalAcceptanceVO(); | ||||
@@ -0,0 +1,33 @@ | |||||
package com.ningdatech.pmapi.projectdeclared.model.dto; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import javax.validation.constraints.NotNull; | |||||
/** | |||||
* @Classname DelayedApplyDTO | |||||
* @Description | |||||
* @Date 2023/5/30 15:35 | |||||
* @Author PoffyZhang | |||||
*/ | |||||
@Data | |||||
@ApiModel(value = "DelayedApplyDTO", description = "延期申请") | |||||
public class DelayedApplyDTO { | |||||
private static final long serialVersionUID = 1L; | |||||
@ApiModelProperty("项目ID") | |||||
@NotNull(message = "项目ID不能为空") | |||||
private Long projectId; | |||||
@ApiModelProperty("延期时长 月") | |||||
@NotNull(message = "请填写时长") | |||||
private Integer delayedMonth; | |||||
@ApiModelProperty("延期理由") | |||||
private String delayedReason; | |||||
@ApiModelProperty("佐证材料") | |||||
private String supportingMaterials; | |||||
} |
@@ -161,15 +161,26 @@ public class AnnualPlanLibManage { | |||||
public void projectApproved(ProjectApprovedReq req) { | public void projectApproved(ProjectApprovedReq req) { | ||||
Project project = projectService.getById(req.getProjectId()); | Project project = projectService.getById(req.getProjectId()); | ||||
stateMachine.pass(project); | stateMachine.pass(project); | ||||
//计划出 计划验收时间 | |||||
LocalDateTime planAcceptanceTime = getPlanAcceptanceTime(req); | |||||
LambdaUpdateWrapper<Project> update = | LambdaUpdateWrapper<Project> update = | ||||
Wrappers.lambdaUpdate(Project.class).set(Project::getApprovalAmount, req.getApprovedAmount()) | Wrappers.lambdaUpdate(Project.class).set(Project::getApprovalAmount, req.getApprovedAmount()) | ||||
.set(Project::getApprovedFile, req.getApprovedFileId()).set(Project::getBuildCycle, req.getBuildCycle()) | .set(Project::getApprovedFile, req.getApprovedFileId()).set(Project::getBuildCycle, req.getBuildCycle()) | ||||
.set(Project::getApprovedConstructionPlanFile, req.getBuildPlanFileId()) | .set(Project::getApprovedConstructionPlanFile, req.getBuildPlanFileId()) | ||||
.set(Project::getApprovalDate, req.getApprovedDate()).set(Project::getStatus, project.getStatus()) | .set(Project::getApprovalDate, req.getApprovedDate()).set(Project::getStatus, project.getStatus()) | ||||
.set(Project::getStage, project.getStage()).eq(Project::getId, req.getProjectId()); | |||||
.set(Project::getStage, project.getStage()) | |||||
.set(Objects.nonNull(planAcceptanceTime),Project::getPlanAcceptanceTime,planAcceptanceTime) | |||||
.eq(Project::getId, req.getProjectId()); | |||||
projectService.update(update); | projectService.update(update); | ||||
} | } | ||||
public LocalDateTime getPlanAcceptanceTime(ProjectApprovedReq req){ | |||||
if (Objects.nonNull(req.getApprovedDate()) && Objects.nonNull(req.getBuildCycle())) { | |||||
return req.getApprovedDate().plusMonths(req.getBuildCycle()); | |||||
} | |||||
return null; | |||||
} | |||||
@Transactional(rollbackFor = Exception.class) | @Transactional(rollbackFor = Exception.class) | ||||
public void suspendAnnualPlan(ProjectIdReq req) { | public void suspendAnnualPlan(ProjectIdReq req) { | ||||
Project project = projectService.getById(req.getProjectId()); | Project project = projectService.getById(req.getProjectId()); | ||||
@@ -40,7 +40,6 @@ import com.ningdatech.pmapi.projectlib.model.vo.ProjectDetailVO; | |||||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | ||||
import com.ningdatech.pmapi.projectlib.service.*; | import com.ningdatech.pmapi.projectlib.service.*; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | ||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||||
import com.wflow.exception.BusinessException; | import com.wflow.exception.BusinessException; | ||||
import com.wflow.workflow.bean.vo.ProcessDetailVO; | import com.wflow.workflow.bean.vo.ProcessDetailVO; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
@@ -73,7 +72,6 @@ public class ProjectLibManage { | |||||
private final ProcessExecuteChainHandle processExecuteHandle; | private final ProcessExecuteChainHandle processExecuteHandle; | ||||
private final RegionCacheHelper regionCacheHelper; | private final RegionCacheHelper regionCacheHelper; | ||||
private final FileService fileService; | private final FileService fileService; | ||||
private final UserInfoHelper userInfoHelper; | |||||
private final IProjectApplicationService projectApplicationService; | private final IProjectApplicationService projectApplicationService; | ||||
private final GenerateProjectCodeUtil generateProjectCodeUtil; | private final GenerateProjectCodeUtil generateProjectCodeUtil; | ||||
private final IProjectInstService projectInstService; | private final IProjectInstService projectInstService; | ||||
@@ -1,5 +1,6 @@ | |||||
package com.ningdatech.pmapi.projectlib.model.entity; | package com.ningdatech.pmapi.projectlib.model.entity; | ||||
import com.alibaba.fastjson.annotation.JSONField; | |||||
import com.baomidou.mybatisplus.annotation.*; | import com.baomidou.mybatisplus.annotation.*; | ||||
import io.swagger.annotations.ApiModel; | import io.swagger.annotations.ApiModel; | ||||
import io.swagger.annotations.ApiModelProperty; | import io.swagger.annotations.ApiModelProperty; | ||||
@@ -347,4 +348,7 @@ public class Project implements Serializable { | |||||
@ApiModelProperty("合同总金额") | @ApiModelProperty("合同总金额") | ||||
private BigDecimal contractAmount; | private BigDecimal contractAmount; | ||||
@ApiModelProperty("计划验收时间") | |||||
private LocalDateTime planAcceptanceTime; | |||||
} | } |
@@ -108,13 +108,6 @@ public class ProjectLibListItemVO { | |||||
@JSONField(format = "yyyy-MM-dd") | @JSONField(format = "yyyy-MM-dd") | ||||
private LocalDateTime planAcceptanceTime; | private LocalDateTime planAcceptanceTime; | ||||
public LocalDateTime getPlanAcceptanceTime(){ | |||||
if (Objects.nonNull(this.approvalDate) && Objects.nonNull(this.buildCycle)) { | |||||
planAcceptanceTime = this.approvalDate.plusMonths(buildCycle); | |||||
} | |||||
return planAcceptanceTime; | |||||
} | |||||
public String getProjectTypeName() { | public String getProjectTypeName() { | ||||
if (Objects.nonNull(this.projectType)) { | if (Objects.nonNull(this.projectType)) { | ||||
Optional.ofNullable(ProjectTypeEnum.getDesc(this.projectType)) | Optional.ofNullable(ProjectTypeEnum.getDesc(this.projectType)) | ||||
@@ -18,9 +18,12 @@ import com.ningdatech.pmapi.user.entity.UserInfo; | |||||
import com.ningdatech.pmapi.user.service.IUserInfoService; | import com.ningdatech.pmapi.user.service.IUserInfoService; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.springframework.beans.factory.annotation.Value; | |||||
import org.springframework.scheduling.annotation.Scheduled; | import org.springframework.scheduling.annotation.Scheduled; | ||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import java.net.InetAddress; | |||||
import java.net.UnknownHostException; | |||||
import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||
import java.time.format.DateTimeFormatter; | import java.time.format.DateTimeFormatter; | ||||
import java.util.List; | import java.util.List; | ||||
@@ -41,8 +44,16 @@ public class CommonLogTask { | |||||
private final static String LOG_RECORD_ADDRESS = "/opt/log/"; | private final static String LOG_RECORD_ADDRESS = "/opt/log/"; | ||||
private final static String LOG_ID_FILE = "logId.txt"; | private final static String LOG_ID_FILE = "logId.txt"; | ||||
private final static String LOG_FILE = "common_log_"; | private final static String LOG_FILE = "common_log_"; | ||||
@Value("${hostname}") | |||||
private String HOST_NAME; | |||||
@Scheduled(fixedDelay = 120000) | @Scheduled(fixedDelay = 120000) | ||||
public void writeLog(){ | |||||
public void writeLog() throws UnknownHostException { | |||||
// | |||||
if (!HOST_NAME.equals(InetAddress.getLocalHost().getHostName())) { | |||||
return; | |||||
} | |||||
//获取记录ID文件 | //获取记录ID文件 | ||||
boolean idFileExist = FileUtil.exist(LOG_RECORD_ADDRESS + LOG_ID_FILE); | boolean idFileExist = FileUtil.exist(LOG_RECORD_ADDRESS + LOG_ID_FILE); | ||||
if (!idFileExist){ | if (!idFileExist){ | ||||
@@ -78,9 +89,9 @@ public class CommonLogTask { | |||||
commonLog.setUserRole("政府工作人员"); | commonLog.setUserRole("政府工作人员"); | ||||
commonLog.setAreaCode(userInfo.getRegionCode()); | commonLog.setAreaCode(userInfo.getRegionCode()); | ||||
String description = optLog.getDescription(); | String description = optLog.getDescription(); | ||||
if (description.equals("登录")){ | |||||
if ("用户登录".equals(description)){ | |||||
commonLog.setActionType(1); | commonLog.setActionType(1); | ||||
}else if (description.equals("退出登录")){ | |||||
}else if (description.contains("退出登录")){ | |||||
commonLog.setActionType(2); | commonLog.setActionType(2); | ||||
}else { | }else { | ||||
commonLog.setActionType(3); | commonLog.setActionType(3); | ||||
@@ -52,10 +52,8 @@ public class TodoCenterController { | |||||
* @param param | * @param param | ||||
* @return | * @return | ||||
*/ | */ | ||||
@GetMapping("/todo-list/{isTemporaryAugment}") | |||||
public PageVo<ResToBeProcessedVO> todoList(@Valid @ModelAttribute ToBeProcessedReq param, | |||||
@PathVariable Integer isTemporaryAugment){ | |||||
param.setIsTemporaryAugment(isTemporaryAugment); | |||||
@GetMapping("/todo-list") | |||||
public PageVo<ResToBeProcessedVO> todoList(@Valid @ModelAttribute ToBeProcessedReq param){ | |||||
return todoCenterManage.todoProjectList(param); | return todoCenterManage.todoProjectList(param); | ||||
} | } | ||||
@@ -66,10 +64,9 @@ public class TodoCenterController { | |||||
* @param response | * @param response | ||||
* @return void | * @return void | ||||
*/ | */ | ||||
@PostMapping("/todo-list/export/{isTemporaryAugment}") | |||||
@PostMapping("/todo-list/export") | |||||
public void exportPendingProjectList(@Valid @RequestBody ToBeProcessedExportReq param, | public void exportPendingProjectList(@Valid @RequestBody ToBeProcessedExportReq param, | ||||
HttpServletResponse response,@PathVariable Integer isTemporaryAugment){ | |||||
param.setIsTemporaryAugment(isTemporaryAugment); | |||||
HttpServletResponse response){ | |||||
todoCenterManage.exportTodoList(response,param); | todoCenterManage.exportTodoList(response,param); | ||||
} | } | ||||
@@ -99,10 +96,8 @@ public class TodoCenterController { | |||||
* @param param | * @param param | ||||
* @return | * @return | ||||
*/ | */ | ||||
@GetMapping("/ido-list/{isTemporaryAugment}") | |||||
public PageVo<ResToBeProcessedVO> idoList(@ModelAttribute ToBeProcessedReq param, | |||||
@PathVariable Integer isTemporaryAugment){ | |||||
param.setIsTemporaryAugment(isTemporaryAugment); | |||||
@GetMapping("/ido-list") | |||||
public PageVo<ResToBeProcessedVO> idoList(@ModelAttribute ToBeProcessedReq param){ | |||||
return todoCenterManage.idoList(param); | return todoCenterManage.idoList(param); | ||||
} | } | ||||
/** | /** | ||||
@@ -112,10 +107,9 @@ public class TodoCenterController { | |||||
* @param response | * @param response | ||||
* @return void | * @return void | ||||
*/ | */ | ||||
@PostMapping("/ido-list/export/{isTemporaryAugment}") | |||||
@PostMapping("/ido-list/export") | |||||
public void exportHandledProjectList(@RequestBody ToBeProcessedExportReq param, | public void exportHandledProjectList(@RequestBody ToBeProcessedExportReq param, | ||||
HttpServletResponse response,@PathVariable Integer isTemporaryAugment){ | |||||
param.setIsTemporaryAugment(isTemporaryAugment); | |||||
HttpServletResponse response){ | |||||
todoCenterManage.idoExport(response,param); | todoCenterManage.idoExport(response,param); | ||||
} | } | ||||
@@ -124,10 +118,8 @@ public class TodoCenterController { | |||||
* @param param | * @param param | ||||
* @return | * @return | ||||
*/ | */ | ||||
@GetMapping("/my-submitted-list/{isTemporaryAugment}") | |||||
public PageVo<ResToBeProcessedVO> mySubmittedList(@ModelAttribute ToBeProcessedReq param, | |||||
@PathVariable Integer isTemporaryAugment){ | |||||
param.setIsTemporaryAugment(isTemporaryAugment); | |||||
@GetMapping("/my-submitted-list") | |||||
public PageVo<ResToBeProcessedVO> mySubmittedList(@ModelAttribute ToBeProcessedReq param){ | |||||
return todoCenterManage.mySubmittedList(param); | return todoCenterManage.mySubmittedList(param); | ||||
} | } | ||||
@@ -138,10 +130,9 @@ public class TodoCenterController { | |||||
* @param response | * @param response | ||||
* @return void | * @return void | ||||
*/ | */ | ||||
@PostMapping("/my-submitted-list/export/{isTemporaryAugment}") | |||||
@PostMapping("/my-submitted-list/export") | |||||
public void exportMySubmittedList(@RequestBody ToBeProcessedExportReq param, | public void exportMySubmittedList(@RequestBody ToBeProcessedExportReq param, | ||||
HttpServletResponse response,@PathVariable Integer isTemporaryAugment){ | |||||
param.setIsTemporaryAugment(isTemporaryAugment); | |||||
HttpServletResponse response){ | |||||
todoCenterManage.exportMySubmittedList(response,param); | todoCenterManage.exportMySubmittedList(response,param); | ||||
} | } | ||||
@@ -150,10 +141,8 @@ public class TodoCenterController { | |||||
* @param param | * @param param | ||||
* @return | * @return | ||||
*/ | */ | ||||
@GetMapping("/ccme-list/{isTemporaryAugment}") | |||||
public PageVo<ResToBeProcessedVO> ccmeList(@Valid @ModelAttribute ToBeProcessedReq param, | |||||
@PathVariable Integer isTemporaryAugment){ | |||||
param.setIsTemporaryAugment(isTemporaryAugment); | |||||
@GetMapping("/ccme-list") | |||||
public PageVo<ResToBeProcessedVO> ccmeList(@Valid @ModelAttribute ToBeProcessedReq param){ | |||||
return todoCenterManage.ccmeList(param); | return todoCenterManage.ccmeList(param); | ||||
} | } | ||||
@@ -164,10 +153,8 @@ public class TodoCenterController { | |||||
* @param response | * @param response | ||||
* @return void | * @return void | ||||
*/ | */ | ||||
@PostMapping("/ccme-list/export/{isTemporaryAugment}") | |||||
public void exportCcMeProjectList(@Valid @RequestBody ToBeProcessedExportReq param, HttpServletResponse response, | |||||
@PathVariable Integer isTemporaryAugment){ | |||||
param.setIsTemporaryAugment(isTemporaryAugment); | |||||
@PostMapping("/ccme-list/export") | |||||
public void exportCcMeProjectList(@Valid @RequestBody ToBeProcessedExportReq param, HttpServletResponse response){ | |||||
todoCenterManage.exportCcMeProjectList(response,param); | todoCenterManage.exportCcMeProjectList(response,param); | ||||
} | } | ||||
@@ -17,6 +17,8 @@ import com.ningdatech.pmapi.todocenter.constant.TodoCenterContant; | |||||
import com.ningdatech.pmapi.todocenter.handle.PassHandle; | import com.ningdatech.pmapi.todocenter.handle.PassHandle; | ||||
import com.ningdatech.pmapi.todocenter.handle.WithDrawHandle; | import com.ningdatech.pmapi.todocenter.handle.WithDrawHandle; | ||||
import com.ningdatech.pmapi.todocenter.model.vo.TodoNumVO; | import com.ningdatech.pmapi.todocenter.model.vo.TodoNumVO; | ||||
import com.wflow.contants.HisProInsEndActId; | |||||
import com.wflow.workflow.enums.ProcessStatusEnum; | |||||
import com.wflow.workflow.utils.ProcessTaskUtils; | import com.wflow.workflow.utils.ProcessTaskUtils; | ||||
import org.apache.commons.io.FileUtils; | import org.apache.commons.io.FileUtils; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
@@ -352,6 +354,9 @@ public class TodoCenterManage { | |||||
.processInstanceId(processInstanceId) | .processInstanceId(processInstanceId) | ||||
.singleResult(); | .singleResult(); | ||||
//提前判断下 是不是 已经被退回了 | |||||
checkIsBack(instance); | |||||
//进入处理逻辑 | //进入处理逻辑 | ||||
switch (param.getAction()) { | switch (param.getAction()) { | ||||
// 通过 | // 通过 | ||||
@@ -434,6 +439,12 @@ public class TodoCenterManage { | |||||
return "操作成功"; | return "操作成功"; | ||||
} | } | ||||
private void checkIsBack(HistoricProcessInstance instance) { | |||||
VUtils.isTrue(Objects.nonNull(instance.getBusinessStatus()) && | |||||
HisProInsEndActId.BACK.equals(instance.getBusinessStatus())) | |||||
.throwMessage("该审核流程已被退回 暂时无法操作!"); | |||||
} | |||||
/** | /** | ||||
* 调用IRS接口,获取盖章后的pdf文件,上传到OSS,并保存文件ID到项目库中 | * 调用IRS接口,获取盖章后的pdf文件,上传到OSS,并保存文件ID到项目库中 | ||||
* @param req | * @param req | ||||
@@ -40,7 +40,7 @@ public class ToBeProcessedReq extends PagePo implements Serializable { | |||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") | ||||
private LocalDateTime createOnMax; | private LocalDateTime createOnMax; | ||||
@ApiModelProperty(value = "是否增补项目",allowableValues = "0,1") | |||||
@ApiModelProperty(value = "是否增补项目") | |||||
private Integer isTemporaryAugment; | private Integer isTemporaryAugment; | ||||
@ApiModelProperty("流程配置ID") | @ApiModelProperty("流程配置ID") | ||||
@@ -0,0 +1,71 @@ | |||||
package com.ningdatech.pmapi.user.controller; | |||||
import cn.hutool.core.date.LocalDateTimeUtil; | |||||
import com.ningdatech.log.model.OptLogDTO; | |||||
import com.ningdatech.log.model.enumeration.LogType; | |||||
import com.ningdatech.log.service.OptLogService; | |||||
import com.ningdatech.log.util.AddressUtil; | |||||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||||
import com.ningdatech.pmapi.user.security.auth.model.WebRequestDetails; | |||||
import lombok.RequiredArgsConstructor; | |||||
import org.springframework.context.event.EventListener; | |||||
import org.springframework.scheduling.annotation.Async; | |||||
import org.springframework.security.authentication.event.AbstractAuthenticationEvent; | |||||
import org.springframework.security.authentication.event.AuthenticationSuccessEvent; | |||||
import org.springframework.security.authentication.event.LogoutSuccessEvent; | |||||
import org.springframework.security.core.Authentication; | |||||
import org.springframework.stereotype.Component; | |||||
import java.time.LocalDateTime; | |||||
/** | |||||
* <p> | |||||
* AuthorizationEventListener | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2023/6/7 | |||||
**/ | |||||
@Component | |||||
@RequiredArgsConstructor | |||||
public class AuthorizationEventListener { | |||||
private final OptLogService optLogService; | |||||
@Async | |||||
@EventListener(AuthenticationSuccessEvent.class) | |||||
public void loginSuccessListener(AuthenticationSuccessEvent event) { | |||||
optLogService.save(buildOptLog("用户登录", event)); | |||||
} | |||||
@Async | |||||
@EventListener(LogoutSuccessEvent.class) | |||||
public void logoutSuccessListener(LogoutSuccessEvent event) { | |||||
optLogService.save(buildOptLog("退出登录", event)); | |||||
} | |||||
private OptLogDTO buildOptLog(String description, AbstractAuthenticationEvent event) { | |||||
Authentication authentication = event.getAuthentication(); | |||||
UserInfoDetails userDetails = (UserInfoDetails) authentication.getPrincipal(); | |||||
WebRequestDetails webDetails = (WebRequestDetails) authentication.getDetails(); | |||||
LocalDateTime now = LocalDateTime.now(); | |||||
OptLogDTO optLog = new OptLogDTO(); | |||||
optLog.setActionMethod(webDetails.getServletPath()); | |||||
optLog.setDescription(description); | |||||
optLog.setStartTime(LocalDateTimeUtil.of(event.getTimestamp())); | |||||
optLog.setFinishTime(now); | |||||
optLog.setCreateOn(now); | |||||
long consumingTime = System.currentTimeMillis() - event.getTimestamp(); | |||||
optLog.setConsumingTime(consumingTime); | |||||
optLog.setHttpMethod(webDetails.getMethod()); | |||||
optLog.setUserName(userDetails.getUsername()); | |||||
optLog.setCreateBy(userDetails.getUserId()); | |||||
optLog.setRequestIp(webDetails.getRequestIp()); | |||||
optLog.setRequestUri(webDetails.getRequestUri()); | |||||
optLog.setRegionByIp(AddressUtil.getRegion(optLog.getRequestIp())); | |||||
optLog.setUa(webDetails.getUserAgent()); | |||||
optLog.setType(LogType.OPT.name()); | |||||
return optLog; | |||||
} | |||||
} |
@@ -8,6 +8,8 @@ import com.ningdatech.pmapi.user.security.auth.agent.AgentAuthSecurityConfig; | |||||
import com.ningdatech.pmapi.user.security.auth.common.CommonAuthSecurityConfig; | import com.ningdatech.pmapi.user.security.auth.common.CommonAuthSecurityConfig; | ||||
import com.ningdatech.pmapi.user.security.auth.credential.CredentialAuthSecurityConfig; | import com.ningdatech.pmapi.user.security.auth.credential.CredentialAuthSecurityConfig; | ||||
import com.ningdatech.pmapi.user.security.auth.handler.DefaultExpiredSessionStrategy; | import com.ningdatech.pmapi.user.security.auth.handler.DefaultExpiredSessionStrategy; | ||||
import com.ningdatech.pmapi.user.security.auth.handler.DefaultLogoutSuccessHandler; | |||||
import lombok.RequiredArgsConstructor; | |||||
import org.springframework.beans.factory.annotation.Qualifier; | import org.springframework.beans.factory.annotation.Qualifier; | ||||
import org.springframework.context.annotation.Configuration; | import org.springframework.context.annotation.Configuration; | ||||
import org.springframework.http.HttpStatus; | import org.springframework.http.HttpStatus; | ||||
@@ -27,29 +29,16 @@ import java.util.Set; | |||||
* @Version 1.0 | * @Version 1.0 | ||||
*/ | */ | ||||
@Configuration | @Configuration | ||||
@RequiredArgsConstructor | |||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | ||||
private final AuthProperties authProperties; | private final AuthProperties authProperties; | ||||
private final CredentialAuthSecurityConfig credentialAuthSecurityConfig; | private final CredentialAuthSecurityConfig credentialAuthSecurityConfig; | ||||
private final LogoutSuccessHandler logoutSuccessHandler; | |||||
private final DefaultLogoutSuccessHandler logoutSuccessHandler; | |||||
private final DefaultExpiredSessionStrategy defaultExpiredSessionStrategy; | private final DefaultExpiredSessionStrategy defaultExpiredSessionStrategy; | ||||
private final AgentAuthSecurityConfig agentAuthSecurityConfig; | private final AgentAuthSecurityConfig agentAuthSecurityConfig; | ||||
private final CommonAuthSecurityConfig commonAuthSecurityConfig; | private final CommonAuthSecurityConfig commonAuthSecurityConfig; | ||||
public WebSecurityConfig(AuthProperties authProperties, | |||||
CredentialAuthSecurityConfig credentialAuthSecurityConfig, | |||||
AgentAuthSecurityConfig agentAuthSecurityConfig, | |||||
CommonAuthSecurityConfig commonAuthSecurityConfig, | |||||
@Qualifier(value = "defaultLogoutSuccessHandler") LogoutSuccessHandler logoutSuccessHandler, | |||||
DefaultExpiredSessionStrategy defaultExpiredSessionStrategy) { | |||||
this.authProperties = authProperties; | |||||
this.credentialAuthSecurityConfig = credentialAuthSecurityConfig; | |||||
this.agentAuthSecurityConfig = agentAuthSecurityConfig; | |||||
this.commonAuthSecurityConfig = commonAuthSecurityConfig; | |||||
this.logoutSuccessHandler = logoutSuccessHandler; | |||||
this.defaultExpiredSessionStrategy = defaultExpiredSessionStrategy; | |||||
} | |||||
@Override | @Override | ||||
protected void configure(HttpSecurity http) throws Exception { | protected void configure(HttpSecurity http) throws Exception { | ||||
assemblerPreAuthUrls(http); | assemblerPreAuthUrls(http); | ||||
@@ -59,27 +48,29 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | |||||
.and().apply(agentAuthSecurityConfig) | .and().apply(agentAuthSecurityConfig) | ||||
.and().apply(commonAuthSecurityConfig) | .and().apply(commonAuthSecurityConfig) | ||||
.and() | .and() | ||||
.authorizeRequests().antMatchers(authProperties.getIgnoreAuthUrlsArray()).permitAll().anyRequest() | |||||
.authorizeRequests() | |||||
.antMatchers(authProperties.getIgnoreAuthUrlsArray()) | |||||
.permitAll() | |||||
.anyRequest() | |||||
.authenticated().and() | .authenticated().and() | ||||
// 防止固定会话攻击,Spring security的默认配置就是如此: | // 防止固定会话攻击,Spring security的默认配置就是如此: | ||||
// 登陆成功之后会创建一个新的会话,然后将旧的session信息复制到新的session中(客户端的sessionId变了) | // 登陆成功之后会创建一个新的会话,然后将旧的session信息复制到新的session中(客户端的sessionId变了) | ||||
.sessionManagement().invalidSessionUrl(authProperties.getInvalidSessionUrl()).sessionFixation() | |||||
.sessionManagement() | |||||
.invalidSessionUrl(authProperties.getInvalidSessionUrl()) | |||||
.sessionFixation() | |||||
.migrateSession() | .migrateSession() | ||||
// .invalidSessionStrategy(defaultInvalidSessionStrategy) | |||||
.maximumSessions(10) | .maximumSessions(10) | ||||
.maxSessionsPreventsLogin(true) | .maxSessionsPreventsLogin(true) | ||||
.expiredSessionStrategy(defaultExpiredSessionStrategy) | .expiredSessionStrategy(defaultExpiredSessionStrategy) | ||||
.and().and() | .and().and() | ||||
.logout().logoutUrl(authProperties.getLogoutUrl()).logoutSuccessHandler(logoutSuccessHandler) | |||||
.logout() | |||||
.logoutUrl(authProperties.getLogoutUrl()) | |||||
.logoutSuccessHandler(logoutSuccessHandler) | |||||
.deleteCookies(CommonConst.COOKIE_KEY) | .deleteCookies(CommonConst.COOKIE_KEY) | ||||
// .and() | |||||
// .cors().configurationSource(corsConfigurationSource()) | |||||
.and() | .and() | ||||
// .csrf().disable(); | |||||
// 开启csrf验证,需要前端同步传入token | // 开启csrf验证,需要前端同步传入token | ||||
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) | .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) | ||||
.ignoringAntMatchers(authProperties.getIgnoreCsrfUrlsArray()); | .ignoringAntMatchers(authProperties.getIgnoreCsrfUrlsArray()); | ||||
// http.anonymous().authenticationFilter(availableUserAuthenticationFilter); | |||||
} | } | ||||
private AuthenticationEntryPoint authenticationEntryPoint() { | private AuthenticationEntryPoint authenticationEntryPoint() { | ||||
@@ -1,6 +1,7 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.agent; | package com.ningdatech.pmapi.user.security.auth.agent; | ||||
import com.ningdatech.basic.exception.BizException; | import com.ningdatech.basic.exception.BizException; | ||||
import com.ningdatech.pmapi.user.security.auth.model.WebRequestDetails; | |||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.springframework.http.HttpMethod; | import org.springframework.http.HttpMethod; | ||||
import org.springframework.security.authentication.AuthenticationServiceException; | import org.springframework.security.authentication.AuthenticationServiceException; | ||||
@@ -13,6 +14,7 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher; | |||||
import javax.servlet.http.HttpServletRequest; | import javax.servlet.http.HttpServletRequest; | ||||
import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||
import java.time.LocalDateTime; | |||||
/** | /** | ||||
* @Author LiuXinXin | * @Author LiuXinXin | ||||
@@ -49,8 +51,7 @@ public class AgentAuthFilter extends AbstractAuthenticationProcessingFilter { | |||||
userId = trim(userId); | userId = trim(userId); | ||||
try { | try { | ||||
AgentAuthToken authRequest = new AgentAuthToken(userId, userId); | AgentAuthToken authRequest = new AgentAuthToken(userId, userId); | ||||
// Allow subclasses to set the "details" property | |||||
setDetails(request, authRequest); | |||||
authRequest.setDetails(new WebRequestDetails(request)); | |||||
return this.getAuthenticationManager().authenticate(authRequest); | return this.getAuthenticationManager().authenticate(authRequest); | ||||
} catch (AuthenticationException e) { | } catch (AuthenticationException e) { | ||||
throw new BadCredentialsException("用户id 不能为空"); | throw new BadCredentialsException("用户id 不能为空"); | ||||
@@ -61,10 +62,6 @@ public class AgentAuthFilter extends AbstractAuthenticationProcessingFilter { | |||||
} | } | ||||
} | } | ||||
protected void setDetails(HttpServletRequest request, AgentAuthToken authRequest) { | |||||
authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); | |||||
} | |||||
private String trim(String trimStr) { | private String trim(String trimStr) { | ||||
if (StringUtils.isNotBlank(trimStr)) { | if (StringUtils.isNotBlank(trimStr)) { | ||||
return trimStr.trim(); | return trimStr.trim(); | ||||
@@ -1,6 +1,7 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.common; | package com.ningdatech.pmapi.user.security.auth.common; | ||||
import com.ningdatech.basic.exception.BizException; | import com.ningdatech.basic.exception.BizException; | ||||
import com.ningdatech.pmapi.user.security.auth.model.WebRequestDetails; | |||||
import com.ningdatech.pmapi.user.security.auth.validate.CommonLoginException; | import com.ningdatech.pmapi.user.security.auth.validate.CommonLoginException; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.springframework.http.HttpMethod; | import org.springframework.http.HttpMethod; | ||||
@@ -55,8 +56,8 @@ public class CommonAuthFilter extends AbstractAuthenticationProcessingFilter { | |||||
platform = trim(platform); | platform = trim(platform); | ||||
credential = trim(credential); | credential = trim(credential); | ||||
try { | try { | ||||
CommonAuthToken authRequest = new CommonAuthToken(platform,credential); | |||||
setDetails(request, authRequest); | |||||
CommonAuthToken authRequest = new CommonAuthToken(platform, credential); | |||||
authRequest.setDetails(new WebRequestDetails(request)); | |||||
return this.getAuthenticationManager().authenticate(authRequest); | return this.getAuthenticationManager().authenticate(authRequest); | ||||
} catch (AuthenticationException e) { | } catch (AuthenticationException e) { | ||||
throw new BadCredentialsException("用户状态"); | throw new BadCredentialsException("用户状态"); | ||||
@@ -67,10 +68,6 @@ public class CommonAuthFilter extends AbstractAuthenticationProcessingFilter { | |||||
} | } | ||||
} | } | ||||
protected void setDetails(HttpServletRequest request, CommonAuthToken authRequest) { | |||||
authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); | |||||
} | |||||
private String trim(String trimStr) { | private String trim(String trimStr) { | ||||
if (StringUtils.isNotBlank(trimStr)) { | if (StringUtils.isNotBlank(trimStr)) { | ||||
return trimStr.trim(); | return trimStr.trim(); | ||||
@@ -2,6 +2,7 @@ package com.ningdatech.pmapi.user.security.auth.credential; | |||||
import com.ningdatech.basic.exception.BizException; | import com.ningdatech.basic.exception.BizException; | ||||
import com.ningdatech.pmapi.user.constant.LoginTypeEnum; | import com.ningdatech.pmapi.user.constant.LoginTypeEnum; | ||||
import com.ningdatech.pmapi.user.security.auth.model.WebRequestDetails; | |||||
import com.ningdatech.pmapi.user.security.auth.validate.CommonLoginException; | import com.ningdatech.pmapi.user.security.auth.validate.CommonLoginException; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.springframework.http.HttpMethod; | import org.springframework.http.HttpMethod; | ||||
@@ -59,17 +60,14 @@ public class CredentialAuthFilter extends AbstractAuthenticationProcessingFilter | |||||
loginType = trim(loginType); | loginType = trim(loginType); | ||||
try { | try { | ||||
CredentialAuthToken authRequest = new CredentialAuthToken(identifier, credential, loginType); | CredentialAuthToken authRequest = new CredentialAuthToken(identifier, credential, loginType); | ||||
// Allow subclasses to set the "details" property | |||||
setDetails(request, authRequest); | |||||
authRequest.setDetails(new WebRequestDetails(request)); | |||||
return this.getAuthenticationManager().authenticate(authRequest); | return this.getAuthenticationManager().authenticate(authRequest); | ||||
} catch (CommonLoginException e) { | } catch (CommonLoginException e) { | ||||
throw new CommonLoginException(e.getMessage()); | throw new CommonLoginException(e.getMessage()); | ||||
} catch (BadCredentialsException e) { | |||||
} catch (BadCredentialsException | BizException e) { | |||||
throw new BadCredentialsException(e.getMessage()); | throw new BadCredentialsException(e.getMessage()); | ||||
} catch (AuthenticationException e) { | } catch (AuthenticationException e) { | ||||
throw new BadCredentialsException("账号或密码错误"); | throw new BadCredentialsException("账号或密码错误"); | ||||
} catch (BizException e) { | |||||
throw new BadCredentialsException(e.getMessage()); | |||||
} catch (Exception e) { | } catch (Exception e) { | ||||
throw new InternalAuthenticationServiceException("授权失败:", e); | throw new InternalAuthenticationServiceException("授权失败:", e); | ||||
} | } | ||||
@@ -0,0 +1,80 @@ | |||||
package com.ningdatech.pmapi.user.security.auth.model; | |||||
import cn.hutool.core.util.StrUtil; | |||||
import cn.hutool.extra.servlet.ServletUtil; | |||||
import org.springframework.security.web.authentication.WebAuthenticationDetails; | |||||
import javax.servlet.http.HttpServletRequest; | |||||
import java.time.LocalDateTime; | |||||
/** | |||||
* <p> | |||||
* WebRequestDetails | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2023/6/7 | |||||
**/ | |||||
public class WebRequestDetails extends WebAuthenticationDetails { | |||||
private static final long serialVersionUID = -4466339683132696235L; | |||||
private LocalDateTime requestTime; | |||||
private final String requestIp; | |||||
private final String requestUri; | |||||
private final String method; | |||||
private final String servletPath; | |||||
private final String requestUrl; | |||||
private final String userAgent; | |||||
/** | |||||
* Records the remote address and will also set the session Id if a session already | |||||
* exists (it won't create one). | |||||
* | |||||
* @param request that the authentication request was received from | |||||
*/ | |||||
public WebRequestDetails(HttpServletRequest request) { | |||||
super(request); | |||||
this.requestUri = request.getRequestURI(); | |||||
this.method = request.getMethod(); | |||||
this.servletPath = request.getServletPath(); | |||||
this.requestUrl = request.getRequestURL().toString(); | |||||
this.requestIp = ServletUtil.getClientIP(request); | |||||
this.userAgent = StrUtil.sub(request.getHeader("user-agent"), 0, 500); | |||||
} | |||||
public LocalDateTime getRequestTime() { | |||||
return requestTime; | |||||
} | |||||
public String getRequestIp() { | |||||
return requestIp; | |||||
} | |||||
public String getRequestUri() { | |||||
return requestUri; | |||||
} | |||||
public String getMethod() { | |||||
return method; | |||||
} | |||||
public String getServletPath() { | |||||
return servletPath; | |||||
} | |||||
public String getRequestUrl() { | |||||
return requestUrl; | |||||
} | |||||
public String getUserAgent() { | |||||
return userAgent; | |||||
} | |||||
} |
@@ -213,4 +213,3 @@ hostname: iZ6mx01gyeodd80imxd2gbZ | |||||
login: | login: | ||||
phone-verify-code: | phone-verify-code: | ||||
skip: true | skip: true | ||||