@@ -6,7 +6,6 @@ import com.ningdatech.pmapi.common.util.ExcelDownUtil; | |||
import com.ningdatech.pmapi.projectdeclared.manage.ProjectAdjustmentManage; | |||
import com.ningdatech.pmapi.projectdeclared.manage.PurchaseManage; | |||
import com.ningdatech.pmapi.projectdeclared.model.dto.PurchaseSaveDTO; | |||
import com.ningdatech.pmapi.projectdeclared.model.dto.PurchaseSaveDTOV1; | |||
import com.ningdatech.pmapi.projectdeclared.model.vo.PurchaseVO; | |||
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | |||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; | |||
@@ -56,19 +55,11 @@ public class PurchaseController { | |||
ExcelDownUtil.downXls(response, req, purchaseManage::exportList); | |||
} | |||
/*@ApiOperation(value = "填写采购结果", notes = "填写采购结果") | |||
@ApiOperation(value = "填写采购结果", notes = "填写采购结果") | |||
@WebLog("填写采购结果") | |||
@PostMapping("/submit-result") | |||
public String submitResult(@Validated @RequestBody PurchaseSaveDTO dto) { | |||
return purchaseManage.submitResult(dto); | |||
}*/ | |||
@ApiOperation(value = "填写采购结果", notes = "填写采购结果") | |||
@WebLog("填写采购结果") | |||
@PostMapping("/submit-result") | |||
public String submitResult(@Validated @RequestBody PurchaseSaveDTOV1 dto) { | |||
return purchaseManage.submitResultV1(dto); | |||
} | |||
} |
@@ -4,7 +4,6 @@ import cn.hutool.core.bean.BeanUtil; | |||
import cn.hutool.core.lang.Assert; | |||
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.exception.BizException; | |||
@@ -12,14 +11,12 @@ 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.PurchaseSaveDTO; | |||
import com.ningdatech.pmapi.projectdeclared.model.dto.PurchaseSaveDTOV1; | |||
import com.ningdatech.pmapi.projectdeclared.model.entity.Purchase; | |||
import com.ningdatech.pmapi.projectdeclared.model.vo.PurchaseVO; | |||
import com.ningdatech.pmapi.projectdeclared.service.IPurchaseService; | |||
@@ -230,60 +227,4 @@ public class PurchaseManage { | |||
return "保存失败"; | |||
} | |||
/** | |||
* 填写采购结果 | |||
* | |||
* @param dto | |||
* @return | |||
*/ | |||
public String submitResultV1(PurchaseSaveDTOV1 dto) { | |||
UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); | |||
String employeeCode = user.getEmployeeCode(); | |||
VUtils.isTrue(StringUtils.isBlank(employeeCode)).throwMessage("获取登录用户 员工号 失败!"); | |||
Long projectId = dto.getProjectId(); | |||
VUtils.isTrue(Objects.isNull(projectId)).throwMessage("提交失败 缺少项目ID!"); | |||
Project project = projectService.getNewProject(dto.getProjectId()); | |||
VUtils.isTrue(Objects.isNull(project)).throwMessage("提交失败 此项目不存在!"); | |||
//首先要判断 项目当前状态 是不是 采购结果备案 | |||
VUtils.isTrue(!ProjectStatusEnum.TO_BE_PURCHASED.eq(project.getStatus()) | |||
|| !ProjectStatusEnum.PROJECT_APPROVED.eq(project.getStage())) | |||
.throwMessage("提交失败 该项目不是 待采购备案状态或者已立项阶段"); | |||
Purchase purchase1 = purchaseService.getOne(Wrappers.lambdaQuery(Purchase.class) | |||
.eq(Purchase::getProjectId, projectId) | |||
.last(BizConst.LIMIT_1)); | |||
Purchase purchase = BeanUtil.copyProperties(dto, Purchase.class); | |||
if (purchase1 == null) { | |||
purchase.setCreateBy(employeeCode); | |||
purchase.setCreateOn(LocalDateTime.now()); | |||
} | |||
purchase.setProjectId(projectId); | |||
if (purchaseService.saveOrUpdate(purchase)) { | |||
// 如果 需要推送项目和应用管理的话 只有遂昌县才有 | |||
// String areaCode = project.getAreaCode(); | |||
// String appCode = dto.getAppCode(); | |||
// if(RegionConst.RC_SC.equals(areaCode) && StringUtils.isNotBlank(appCode)){ | |||
// try{ | |||
// | |||
// }catch (Exception e){ | |||
// log.info("绑定以及推送项目和应用关系 失败! {}" + e.getMessage()); | |||
// } | |||
// } | |||
//进入到下一状态 | |||
stateMachineUtils.pass(project); | |||
project.setUpdateOn(LocalDateTime.now()); | |||
// 获取总的成交时间及金额 | |||
project.setTransactionAmount(purchase.getTransactionAmount()); | |||
project.setTransactionTime(purchase.getTransactionTime()); | |||
projectService.updateById(project); | |||
return "填写成功"; | |||
} | |||
return "保存失败"; | |||
} | |||
} |
@@ -1,62 +0,0 @@ | |||
package com.ningdatech.pmapi.projectdeclared.model.dto; | |||
import com.fasterxml.jackson.annotation.JsonFormat; | |||
import io.swagger.annotations.ApiModel; | |||
import io.swagger.annotations.ApiModelProperty; | |||
import lombok.AllArgsConstructor; | |||
import lombok.Data; | |||
import javax.validation.constraints.NotNull; | |||
import java.math.BigDecimal; | |||
import java.time.LocalDateTime; | |||
/** | |||
* @Classname Purchase | |||
* @Description | |||
* @Date 2023/5/29 10:00 | |||
* @Author PoffyZhang | |||
*/ | |||
@Data | |||
@ApiModel(value = "采购对象", description = "采购对象") | |||
@AllArgsConstructor | |||
public class PurchaseSaveDTOV1 { | |||
@ApiModelProperty("项目ID") | |||
@NotNull(message = "请传项目ID") | |||
private Long projectId; | |||
@ApiModelProperty("供应商") | |||
private String supplier; | |||
@ApiModelProperty("供应商联系人") | |||
private String supplierContact; | |||
@ApiModelProperty("供应商联系方式") | |||
private String supplierContactInfo; | |||
@ApiModelProperty("采购方式 1公开招标 2自行采购") | |||
private Integer purchaseMethod; | |||
@ApiModelProperty("成交金额") | |||
private BigDecimal transactionAmount; | |||
@ApiModelProperty("成交时间") | |||
@JsonFormat(pattern = "yyyy-MM-dd") | |||
private LocalDateTime transactionTime; | |||
@ApiModelProperty("代理机构") | |||
private String agency; | |||
@ApiModelProperty("投标文件") | |||
private String biddingDoc; | |||
@ApiModelProperty("招标文件") | |||
private String bidDoc; | |||
@ApiModelProperty("中标通知书") | |||
private String acceptanceLetter; | |||
@ApiModelProperty("应用编码") | |||
private String appCode; | |||
} |
@@ -0,0 +1,39 @@ | |||
package com.ningdatech.pmapi.sys.controller; | |||
import com.ningdatech.pmapi.projectlib.enumeration.InstTypeEnum; | |||
import com.ningdatech.pmapi.sys.manage.ProcessStatisticsManage; | |||
import com.ningdatech.pmapi.sys.model.vo.ProcessDetailStatVO; | |||
import lombok.AllArgsConstructor; | |||
import org.springframework.validation.annotation.Validated; | |||
import org.springframework.web.bind.annotation.GetMapping; | |||
import org.springframework.web.bind.annotation.RequestMapping; | |||
import org.springframework.web.bind.annotation.RequestParam; | |||
import org.springframework.web.bind.annotation.RestController; | |||
import javax.validation.Valid; | |||
import javax.validation.constraints.NotNull; | |||
import java.util.concurrent.TimeUnit; | |||
/** | |||
* <p> | |||
* ProcessStatisticsController | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 2023/7/31 | |||
**/ | |||
@Validated | |||
@RestController | |||
@RequestMapping("/api/v1/process/statistics") | |||
@AllArgsConstructor | |||
public class ProcessStatisticsController { | |||
private final ProcessStatisticsManage processStatisticsManage; | |||
@GetMapping("detailByInstType") | |||
public ProcessDetailStatVO processDetailStat(@RequestParam(required = false, defaultValue = "DAYS") TimeUnit unit, | |||
@Valid @NotNull(message = "流程类型不能为空") InstTypeEnum instType) { | |||
return processStatisticsManage.processDetailStat(unit, instType); | |||
} | |||
} |
@@ -0,0 +1,74 @@ | |||
package com.ningdatech.pmapi.sys.manage; | |||
import cn.hutool.core.util.NumberUtil; | |||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.ningdatech.basic.exception.BizException; | |||
import com.ningdatech.basic.util.CollUtils; | |||
import com.ningdatech.pmapi.projectlib.enumeration.InstTypeEnum; | |||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | |||
import com.ningdatech.pmapi.sys.model.vo.ProcessDetailStatVO; | |||
import lombok.AllArgsConstructor; | |||
import org.flowable.engine.HistoryService; | |||
import org.flowable.engine.history.HistoricProcessInstance; | |||
import org.springframework.stereotype.Component; | |||
import java.util.HashSet; | |||
import java.util.List; | |||
import java.util.LongSummaryStatistics; | |||
import java.util.concurrent.TimeUnit; | |||
import java.util.stream.Collectors; | |||
/** | |||
* <p> | |||
* ProcessStatisticsManage | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 2023/7/31 | |||
**/ | |||
@Component | |||
@AllArgsConstructor | |||
public class ProcessStatisticsManage { | |||
private final HistoryService historyService; | |||
private final IProjectInstService projectInstService; | |||
public ProcessDetailStatVO processDetailStat(TimeUnit unit, InstTypeEnum instType) { | |||
if (!TimeUnit.DAYS.equals(unit) && !TimeUnit.HOURS.equals(unit)) { | |||
throw BizException.wrap("仅支持以天和小时为单位的统计"); | |||
} | |||
ProcessDetailStatVO detailStat = ProcessDetailStatVO.init(); | |||
LambdaQueryWrapper<ProjectInst> modelQuery = Wrappers.lambdaQuery(ProjectInst.class) | |||
.select(ProjectInst::getInstCode) | |||
.eq(ProjectInst::getInstType, instType.getCode()); | |||
List<ProjectInst> projectInsts = projectInstService.list(modelQuery); | |||
if (projectInsts.isEmpty()) { | |||
return detailStat; | |||
} | |||
List<String> instCodeList = CollUtils.fieldList(projectInsts, ProjectInst::getInstCode); | |||
List<HistoricProcessInstance> instances = historyService.createHistoricProcessInstanceQuery() | |||
.processInstanceIds(new HashSet<>(instCodeList)) | |||
.list(); | |||
detailStat.setTotalInst(instances.size()); | |||
LongSummaryStatistics statistics = instances.stream().filter(w -> { | |||
boolean finished = w.getEndTime() != null; | |||
if (finished) { | |||
detailStat.incrFinished(); | |||
} else { | |||
detailStat.incrPending(); | |||
} | |||
return finished; | |||
}).map(HistoricProcessInstance::getDurationInMillis) | |||
.collect(Collectors.summarizingLong(Long::longValue)); | |||
if (detailStat.getFinishedInst() != 0) { | |||
long unitMillis = unit.toMillis(1); | |||
detailStat.setAvgTime(NumberUtil.div(statistics.getAverage(), unitMillis, 1)); | |||
detailStat.setMaxTime(NumberUtil.div(statistics.getMax(), unitMillis, 1)); | |||
detailStat.setMinTime(NumberUtil.div(statistics.getMin(), unitMillis, 1)); | |||
} | |||
return detailStat; | |||
} | |||
} |
@@ -0,0 +1,56 @@ | |||
package com.ningdatech.pmapi.sys.model.vo; | |||
import io.swagger.annotations.ApiModelProperty; | |||
import lombok.Data; | |||
import java.util.concurrent.TimeUnit; | |||
/** | |||
* <p> | |||
* ProcessDetailStatVO | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 2023/7/31 | |||
**/ | |||
@Data | |||
public class ProcessDetailStatVO { | |||
@ApiModelProperty("流程实例总数") | |||
private Integer totalInst; | |||
@ApiModelProperty("已完成流程实例数") | |||
private Integer finishedInst; | |||
@ApiModelProperty("已完成流程实例数") | |||
private Integer pendingInst; | |||
@ApiModelProperty("平均耗时") | |||
private double avgTime; | |||
@ApiModelProperty("最长耗时") | |||
private double maxTime; | |||
@ApiModelProperty("最短耗时") | |||
private double minTime; | |||
@ApiModelProperty("时间单位") | |||
private TimeUnit timeUnit; | |||
public static ProcessDetailStatVO init() { | |||
ProcessDetailStatVO stat = new ProcessDetailStatVO(); | |||
stat.setFinishedInst(0); | |||
stat.setTotalInst(0); | |||
stat.setPendingInst(0); | |||
return stat; | |||
} | |||
public void incrPending() { | |||
this.pendingInst += 1; | |||
} | |||
public void incrFinished() { | |||
this.finishedInst += 1; | |||
} | |||
} |
@@ -3,26 +3,21 @@ package com.ningdatech.pmapi.instance; | |||
import cn.hutool.core.collection.CollUtil; | |||
import com.alibaba.fastjson.JSON; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.ningdatech.basic.model.PageVo; | |||
import com.ningdatech.pmapi.AppTests; | |||
import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage; | |||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | |||
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | |||
import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | |||
import com.wflow.contants.ProcessConstant; | |||
import com.wflow.workflow.bean.dto.ProcessInstanceUserDto; | |||
import com.wflow.workflow.bean.dto.TodoCenterListReqDTO; | |||
import com.wflow.workflow.enums.ProcessHandlerEnum; | |||
import org.flowable.engine.HistoryService; | |||
import org.flowable.engine.RuntimeService; | |||
import org.flowable.engine.history.HistoricActivityInstance; | |||
import org.flowable.engine.history.HistoricProcessInstance; | |||
import org.flowable.engine.runtime.ActivityInstance; | |||
import org.flowable.task.api.history.HistoricTaskInstance; | |||
import org.flowable.task.service.history.NativeHistoricTaskInstanceQuery; | |||
import org.flowable.variable.api.history.HistoricVariableInstance; | |||
import org.junit.Test; | |||
import org.springframework.beans.BeanUtils; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import java.util.*; | |||
@@ -49,7 +44,7 @@ public class InstanceTest extends AppTests { | |||
private IProjectInstService projectInstService; | |||
@Test | |||
public void test(){ | |||
public void test() { | |||
String instanceId = "896fa188-96d8-11ed-9539-e2d4e8f16b2f"; | |||
Object user = runtimeService.getVariable(instanceId, | |||
"owner"); | |||
@@ -57,7 +52,7 @@ public class InstanceTest extends AppTests { | |||
} | |||
@Test | |||
public void testHistory(){ | |||
public void testHistory() { | |||
//如果有已经被审核过的 节点 | |||
List<HistoricActivityInstance> finished = historyService.createHistoricActivityInstanceQuery() | |||
.processInstanceId("085af7ef-d133-11ed-a3f6-02426daa406d").finished() | |||
@@ -68,7 +63,7 @@ public class InstanceTest extends AppTests { | |||
} | |||
@Test | |||
public void testRuntime(){ | |||
public void testRuntime() { | |||
//如果有已经被审核过的 节点 | |||
List<ActivityInstance> userTask = runtimeService.createActivityInstanceQuery() | |||
.processInstanceId("1709ebe3-d148-11ed-9351-02426daa406d") | |||
@@ -78,7 +73,7 @@ public class InstanceTest extends AppTests { | |||
} | |||
@Test | |||
public void testTodo(){ | |||
public void testTodo() { | |||
String employeeCode = "GE_e9d5c7917acd4eeea04ff2a9454af62e"; | |||
// 查出项目库项目 | |||
ProjectListReq projectListReq = new ProjectListReq(); | |||
@@ -93,7 +88,7 @@ public class InstanceTest extends AppTests { | |||
List<ProjectInst> projectInstList = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class) | |||
.in(ProjectInst::getProjectId, projectIdList) | |||
.orderByDesc(ProjectInst::getProjectId)); | |||
Map<String, Project> projectInfoMap = projectInstList.stream().collect(Collectors.toMap(ProjectInst::getInstCode, p-> projectsMap.get(p.getProjectId()))); | |||
Map<String, Project> projectInfoMap = projectInstList.stream().collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId()))); | |||
List<String> instCodes = projectInstList.stream().map(ProjectInst::getInstCode).collect(Collectors.toList()); | |||
// 查出用户工作流 | |||
@@ -108,7 +103,7 @@ public class InstanceTest extends AppTests { | |||
historyService.createNativeHistoricTaskInstanceQuery().sql(nativeSql); | |||
List<HistoricTaskInstance> taskInstances = taskInstanceQuery.list(); | |||
Set set = new HashSet(); | |||
Set<String> set = new HashSet<>(); | |||
List<HistoricTaskInstance> taskInstanceList = taskInstances.stream() | |||
.filter(t -> instCodes.contains(t.getProcessInstanceId())) | |||
.sorted(Comparator.comparing(HistoricTaskInstance::getEndTime)).collect(Collectors.toList()) | |||
@@ -120,14 +115,34 @@ public class InstanceTest extends AppTests { | |||
} | |||
@Test | |||
public void test2(){ | |||
public void test2() { | |||
// 获取节点处理结果 | |||
// Map<String, ProcessHandlerEnum> varMap = historyService.createHistoricVariableInstanceQuery() | |||
// .processInstanceId("e99fe24c-d21c-11ed-af5d-02426daa406d") | |||
// .variableNameLike("approve_%") | |||
// .list().stream() | |||
// .collect(Collectors.toMap(HistoricVariableInstance::getVariableName, v -> (ProcessHandlerEnum) v.getValue())); | |||
runtimeService.removeVariable("564102ce-d1ff-11ed-b694-02424b2b849f","approve_7d2a191a-d1ff-11ed-b694-02424b2b849f"); | |||
runtimeService.removeVariable("564102ce-d1ff-11ed-b694-02424b2b849f", "approve_7d2a191a-d1ff-11ed-b694-02424b2b849f"); | |||
System.out.println(1); | |||
} | |||
@Test | |||
public void usageTimeStat() { | |||
// 查询所有已完成的流程实例 | |||
List<HistoricProcessInstance> processInstanceList = historyService.createHistoricProcessInstanceQuery() | |||
.orderByProcessInstanceStartTime() | |||
.desc() | |||
.finished() | |||
.list(); | |||
// 统计每个流程实例的审批耗时 | |||
for (HistoricProcessInstance processInstance : processInstanceList) { | |||
System.out.println("流程实例ID:" + processInstance.getId()); | |||
System.out.println("流程开始时间:" + processInstance.getStartTime()); | |||
System.out.println("流程结束时间:" + processInstance.getEndTime()); | |||
System.out.println("流程耗时(ms):" + processInstance.getDurationInMillis() / 1000); | |||
System.out.println("================================================================"); | |||
} | |||
} | |||
} |
@@ -1,3 +1,3 @@ | |||
spring: | |||
profiles: | |||
active: prod | |||
active: dev |