@@ -32,7 +32,8 @@ public enum ProjectProcessType { | |||||
COMPLIANCE_REVIEW(13, "合规性审查审批流程"), | COMPLIANCE_REVIEW(13, "合规性审查审批流程"), | ||||
PROJECT_REVIEW(14, "项目复核审批流程"), | PROJECT_REVIEW(14, "项目复核审批流程"), | ||||
PROJECT_STOPPED(15, "项目终止审批流程"), | PROJECT_STOPPED(15, "项目终止审批流程"), | ||||
PROJECT_CHANGE(16, "项目变更审批流程"); | |||||
PROJECT_CHANGE(16, "项目变更审批流程"), | |||||
PURCHASE_NOTICE(17, "采购公告审批流程"); | |||||
private final Integer code; | private final Integer code; | ||||
private final String desc; | private final String desc; | ||||
@@ -5,6 +5,7 @@ import com.hz.pm.api.common.statemachine.event.TenderStateChangeEvent; | |||||
import com.hz.pm.api.projectdeclared.model.entity.Purchase; | import com.hz.pm.api.projectdeclared.model.entity.Purchase; | ||||
import com.hz.pm.api.projectlib.model.enumeration.status.TenderAdaptStatus; | import com.hz.pm.api.projectlib.model.enumeration.status.TenderAdaptStatus; | ||||
import com.hz.pm.api.projectlib.model.enumeration.status.TenderMainStatus; | import com.hz.pm.api.projectlib.model.enumeration.status.TenderMainStatus; | ||||
import com.hz.pm.api.projectlib.model.enumeration.status.TenderXcfhxApplyStatus; | |||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.springframework.messaging.Message; | import org.springframework.messaging.Message; | ||||
import org.springframework.statemachine.annotation.OnTransition; | import org.springframework.statemachine.annotation.OnTransition; | ||||
@@ -25,6 +26,51 @@ import static com.hz.pm.api.common.statemachine.action.TenderStateChangeActionUt | |||||
public class TenderStateChangeAction { | public class TenderStateChangeAction { | ||||
/** | /** | ||||
* 提交采购公告 | |||||
* | |||||
* @param message \ | |||||
*/ | |||||
@OnTransition(source = "TO_BE_SUBMIT_PURCHASE_NOTICE", target = "ON_PURCHASE_NOTICE_APPLY") | |||||
public void SUBMIT_PURCHASE_NOTICE(Message<TenderStateChangeEvent> message) { | |||||
Purchase purchase = getPurchaseInfo(message); | |||||
purchase.setStatus(TenderMainStatus.ON_PURCHASE_NOTICE_APPLY.getCode()); | |||||
} | |||||
/** | |||||
* 重新提交采购公告 | |||||
* | |||||
* @param message \ | |||||
*/ | |||||
@OnTransition(source = "PURCHASE_NOTICE_FAILED", target = "ON_PURCHASE_NOTICE_APPLY") | |||||
public void RESUBMIT_PURCHASE_NOTICE(Message<TenderStateChangeEvent> message) { | |||||
Purchase purchase = getPurchaseInfo(message); | |||||
purchase.setStatus(TenderMainStatus.ON_PURCHASE_NOTICE_APPLY.getCode()); | |||||
} | |||||
/** | |||||
* 采购公告审核通过 | |||||
* | |||||
* @param message \ | |||||
*/ | |||||
@OnTransition(source = "ON_PURCHASE_NOTICE_APPLY", target = "TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO") | |||||
public void PURCHASE_NOTICE_PASSED(Message<TenderStateChangeEvent> message) { | |||||
Purchase purchase = getPurchaseInfo(message); | |||||
purchase.setXcfhxApplyStatus(TenderXcfhxApplyStatus.TO_BE_SUBMIT_XCFHX_APPLY.getCode()); | |||||
purchase.setStatus(TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO.getCode()); | |||||
} | |||||
/** | |||||
* 采购公告审核不通过 | |||||
* | |||||
* @param message \ | |||||
*/ | |||||
@OnTransition(source = "ON_PURCHASE_NOTICE_APPLY", target = "PURCHASE_NOTICE_FAILED") | |||||
public void PURCHASE_NOTICE_FAILED(Message<TenderStateChangeEvent> message) { | |||||
Purchase purchase = getPurchaseInfo(message); | |||||
purchase.setStatus(TenderMainStatus.PURCHASE_NOTICE_FAILED.getCode()); | |||||
} | |||||
/** | |||||
* 填写合同信息 | * 填写合同信息 | ||||
* | * | ||||
* @param message \ | * @param message \ | ||||
@@ -78,9 +78,33 @@ public class TenderStateMachineBuilderImpl implements BaseStateMachineBuilder<Pu | |||||
builder.configureStates() | builder.configureStates() | ||||
.withStates() | .withStates() | ||||
.initial(TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO) | |||||
.initial(TenderMainStatus.TO_BE_SUBMIT_PURCHASE_NOTICE) | |||||
.states(new HashSet<>(states)); | .states(new HashSet<>(states)); | ||||
builder.configureTransitions() | builder.configureTransitions() | ||||
// 发布采购公告 | |||||
.withExternal() | |||||
.source(TenderMainStatus.TO_BE_SUBMIT_PURCHASE_NOTICE) | |||||
.target(TenderMainStatus.ON_PURCHASE_NOTICE_APPLY) | |||||
.event(TenderStateChangeEvent.SUBMIT_PURCHASE_NOTICE) | |||||
.and() | |||||
// 采购公告审核通过 | |||||
.withExternal() | |||||
.source(TenderMainStatus.ON_PURCHASE_NOTICE_APPLY) | |||||
.target(TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO) | |||||
.event(TenderStateChangeEvent.PURCHASE_NOTICE_PASSED) | |||||
.and() | |||||
// 重新发布采购公告 | |||||
.withExternal() | |||||
.source(TenderMainStatus.PURCHASE_NOTICE_FAILED) | |||||
.target(TenderMainStatus.ON_PURCHASE_NOTICE_APPLY) | |||||
.event(TenderStateChangeEvent.RESUBMIT_PURCHASE_NOTICE) | |||||
.and() | |||||
// 采购公告审核不通过 | |||||
.withExternal() | |||||
.source(TenderMainStatus.ON_PURCHASE_NOTICE_APPLY) | |||||
.target(TenderMainStatus.PURCHASE_NOTICE_FAILED) | |||||
.event(TenderStateChangeEvent.PURCHASE_NOTICE_FAILED) | |||||
.and() | |||||
// 填写采购&合同信息 | // 填写采购&合同信息 | ||||
.withExternal() | .withExternal() | ||||
.source(TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO) | .source(TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO) | ||||
@@ -15,6 +15,11 @@ import lombok.Getter; | |||||
@AllArgsConstructor | @AllArgsConstructor | ||||
public enum TenderStateChangeEvent implements AbstractStateChangeEvent { | public enum TenderStateChangeEvent implements AbstractStateChangeEvent { | ||||
SUBMIT_PURCHASE_NOTICE(100, null, null), | |||||
RESUBMIT_PURCHASE_NOTICE(108, null, null), | |||||
PURCHASE_NOTICE_PASSED(107, null, null), | |||||
PURCHASE_NOTICE_FAILED(null, 108, null), | |||||
/** | /** | ||||
* 填写采购&合同信息 | * 填写采购&合同信息 | ||||
*/ | */ | ||||
@@ -96,6 +96,8 @@ public enum MHTodoTypeEnum { | |||||
"instanceId=${instanceId}&projectId=${projectId}&nodeId=${nodeId}&taskId=${taskId}&bidId=${bizId}&userId=${userId}&userName=${userName}&path=${path}"), | "instanceId=${instanceId}&projectId=${projectId}&nodeId=${nodeId}&taskId=${taskId}&bidId=${bizId}&userId=${userId}&userName=${userName}&path=${path}"), | ||||
FINAL_INSPECT_AUDIT("终验审批", null, "您单位的【%s】已通过终验审核。", null, null, | FINAL_INSPECT_AUDIT("终验审批", null, "您单位的【%s】已通过终验审核。", null, null, | ||||
"instanceId=${instanceId}&projectId=${projectId}&nodeId=${nodeId}&taskId=${taskId}&bidId=${bizId}&userId=${userId}&userName=${userName}&path=${path}"), | "instanceId=${instanceId}&projectId=${projectId}&nodeId=${nodeId}&taskId=${taskId}&bidId=${bizId}&userId=${userId}&userName=${userName}&path=${path}"), | ||||
PURCHASE_NOTICE_AUDIT("采购公告审批", WITHOUT_PURCHASE_CONTRACT, null, null, null, | |||||
"instanceId=${instanceId}&projectId=${projectId}&nodeId=${nodeId}&taskId=${taskId}&bidId=${bizId}&userId=${userId}&userName=${userName}&path=${path}"), | |||||
XCFHX_INSPECT_AUDIT("信创符合性审查审批", WITHOUT_BUILD_SCHEME, null, null, null, | XCFHX_INSPECT_AUDIT("信创符合性审查审批", WITHOUT_BUILD_SCHEME, null, null, null, | ||||
"instanceId=${instanceId}&projectId=${projectId}&nodeId=${nodeId}&taskId=${taskId}&bidId=${bizId}&userId=${userId}&userName=${userName}&path=${path}&xinchuangId={xinchuangId}"), | "instanceId=${instanceId}&projectId=${projectId}&nodeId=${nodeId}&taskId=${taskId}&bidId=${bizId}&userId=${userId}&userName=${userName}&path=${path}&xinchuangId={xinchuangId}"), | ||||
DECLARED_RECORD_AUDIT("立项备案审批", WITHOUT_PURCHASE_NOTICE, null, null, null, | DECLARED_RECORD_AUDIT("立项备案审批", WITHOUT_PURCHASE_NOTICE, null, null, null, | ||||
@@ -81,6 +81,13 @@ public class PurchaseController { | |||||
purchaseManage.submitPurchaseNotice(req); | purchaseManage.submitPurchaseNotice(req); | ||||
} | } | ||||
@ApiOperation("重新发布采购公告") | |||||
@WebLog("重新发布采购公告") | |||||
@PostMapping("/notice/resubmit") | |||||
public void resubmitPurchaseNotice(@RequestBody SubmitPurchaseNoticeReq req) { | |||||
purchaseManage.resubmitPurchaseNotice(req); | |||||
} | |||||
@ApiOperation("新增采购公告") | @ApiOperation("新增采购公告") | ||||
@WebLog("新增采购公告") | @WebLog("新增采购公告") | ||||
@PostMapping("/notice/append") | @PostMapping("/notice/append") | ||||
@@ -98,6 +98,9 @@ import java.util.concurrent.atomic.AtomicInteger; | |||||
import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||
import java.util.stream.Stream; | import java.util.stream.Stream; | ||||
import static com.hz.pm.api.projectlib.model.enumeration.status.TenderMainStatus.PURCHASE_NOTICE_FAILED; | |||||
import static com.hz.pm.api.projectlib.model.enumeration.status.TenderMainStatus.TO_BE_SUBMIT_PURCHASE_NOTICE; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
* PurchaseManage | * PurchaseManage | ||||
@@ -166,15 +169,23 @@ public class PurchaseManage { | |||||
Map<Long, Collection<Purchase>> projectPurchaseMap = CollUtils.listToMap(projects, Project::getId, | Map<Long, Collection<Purchase>> projectPurchaseMap = CollUtils.listToMap(projects, Project::getId, | ||||
w -> CollUtil.filterNew(purchases, x -> x.getProjectId().equals(w.getId()))); | w -> CollUtil.filterNew(purchases, x -> x.getProjectId().equals(w.getId()))); | ||||
PurchaseProgressStatVO stat = new PurchaseProgressStatVO(); | PurchaseProgressStatVO stat = new PurchaseProgressStatVO(); | ||||
stat.setOnPurchaseCount(CollUtil.count(projectPurchaseMap.values(), | |||||
w -> CollUtil.anyMatch(w, x -> TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO.eq(x.getStatus())))); | |||||
stat.setToBePurchaseCount(CollUtil.count(projectPurchaseMap.values(), Collection::isEmpty)); | stat.setToBePurchaseCount(CollUtil.count(projectPurchaseMap.values(), Collection::isEmpty)); | ||||
// 采购中 | |||||
stat.setOnPurchaseCount(CollUtil.count(projectPurchaseMap.values(), | |||||
w -> CollUtil.anyMatch(w, x -> PURCHASING_STATUS.contains(x.getStatus())))); | |||||
// 已采购 | |||||
stat.setPurchaseFinishedCount(CollUtil.count(projectPurchaseMap.values(), | stat.setPurchaseFinishedCount(CollUtil.count(projectPurchaseMap.values(), | ||||
w -> !w.isEmpty() && CollUtil.allMatch(w, x -> !TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO.eq(x.getStatus())))); | |||||
w -> !w.isEmpty() && CollUtil.anyMatch(w, x -> !PURCHASING_STATUS.contains(x.getStatus())))); | |||||
stat.setTotalCount(projects.size()); | stat.setTotalCount(projects.size()); | ||||
return stat; | return stat; | ||||
} | } | ||||
private static final List<Integer> PURCHASING_STATUS = Arrays.asList( | |||||
TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO.getCode(), | |||||
TenderMainStatus.PURCHASE_NOTICE_FAILED.getCode(), | |||||
TenderMainStatus.ON_PURCHASE_NOTICE_APPLY.getCode()); | |||||
/** | /** | ||||
* 待采购的-项目列表 | * 待采购的-项目列表 | ||||
* | * | ||||
@@ -198,8 +209,8 @@ public class PurchaseManage { | |||||
ProjectManageUtil.projectBaseQuery(query); | ProjectManageUtil.projectBaseQuery(query); | ||||
if (req.getTabStatus() != null) { | if (req.getTabStatus() != null) { | ||||
if (TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO.eq(req.getTabStatus())) { | if (TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO.eq(req.getTabStatus())) { | ||||
query.exists(ExistsSqlConst.PROJECT_EXISTS_PURCHASE + | |||||
" and np.status = {0} ", req.getTabStatus()); | |||||
String inSql = BizUtils.inSqlJoin(CollUtils.convert(PURCHASING_STATUS, String::valueOf)); | |||||
query.exists(ExistsSqlConst.PROJECT_EXISTS_PURCHASE + " and np.status in " + inSql); | |||||
} else if (TenderMainStatus.PURCHASE_FINISHED.eq(req.getTabStatus())) { | } else if (TenderMainStatus.PURCHASE_FINISHED.eq(req.getTabStatus())) { | ||||
query.exists(ExistsSqlConst.PROJECT_EXISTS_STATUS_CHANGE + | query.exists(ExistsSqlConst.PROJECT_EXISTS_STATUS_CHANGE + | ||||
" and npsc.event = {0} ", ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD); | " and npsc.event = {0} ", ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD); | ||||
@@ -222,13 +233,11 @@ public class PurchaseManage { | |||||
List<Long> projectIds = CollUtils.fieldList(page.getRecords(), Project::getId); | List<Long> projectIds = CollUtils.fieldList(page.getRecords(), Project::getId); | ||||
LambdaQueryWrapper<Purchase> purchaseQuery = Wrappers.lambdaQuery(Purchase.class) | LambdaQueryWrapper<Purchase> purchaseQuery = Wrappers.lambdaQuery(Purchase.class) | ||||
.in(Purchase::getProjectId, projectIds); | .in(Purchase::getProjectId, projectIds); | ||||
if (req.getTabStatus() != null) { | |||||
if (TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO.eq(req.getTabStatus())) { | |||||
purchaseQuery.eq(Purchase::getStatus, req.getTabStatus()); | |||||
} else if (TenderMainStatus.PURCHASE_FINISHED.eq(req.getTabStatus())) { | |||||
purchaseQuery.exists(ExistsSqlConst.PURCHASE_EXISTS_STATUS_CHANGE + | |||||
" and npsc.event = {0} ", TenderStateChangeEvent.SUBMIT_PURCHASE_CONSTRUCTION_INFO); | |||||
} | |||||
if (TenderMainStatus.PURCHASE_FINISHED.eq(req.getTabStatus())) { | |||||
purchaseQuery.exists(ExistsSqlConst.PURCHASE_EXISTS_STATUS_CHANGE + | |||||
" and npsc.event = {0} ", TenderStateChangeEvent.SUBMIT_PURCHASE_CONSTRUCTION_INFO); | |||||
} else { | |||||
purchaseQuery.in(Purchase::getStatus, PURCHASING_STATUS); | |||||
} | } | ||||
List<Purchase> purchases = purchaseService.list(purchaseQuery); | List<Purchase> purchases = purchaseService.list(purchaseQuery); | ||||
purchaseMap = CollUtils.group(purchases, Purchase::getProjectId); | purchaseMap = CollUtils.group(purchases, Purchase::getProjectId); | ||||
@@ -259,11 +268,11 @@ public class PurchaseManage { | |||||
if (currPurchases != null) { | if (currPurchases != null) { | ||||
List<TenderListInfoVO> tenders = new ArrayList<>(); | List<TenderListInfoVO> tenders = new ArrayList<>(); | ||||
for (Purchase x : currPurchases) { | for (Purchase x : currPurchases) { | ||||
TenderMainStatus tenderMainStatus; | |||||
if (!TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO.eq(x.getStatus())) { | |||||
ITenderStatus tenderMainStatus; | |||||
if (!PURCHASING_STATUS.contains(x.getStatus())) { | |||||
tenderMainStatus = TenderMainStatus.PURCHASE_FINISHED; | tenderMainStatus = TenderMainStatus.PURCHASE_FINISHED; | ||||
} else { | } else { | ||||
tenderMainStatus = TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO; | |||||
tenderMainStatus = TenderMainStatus.getNoNull(x.getStatus()); | |||||
} | } | ||||
TenderListInfoVO tender = new TenderListInfoVO(); | TenderListInfoVO tender = new TenderListInfoVO(); | ||||
tender.setBidName(x.getBidName()); | tender.setBidName(x.getBidName()); | ||||
@@ -409,87 +418,94 @@ public class PurchaseManage { | |||||
@Transactional(rollbackFor = Exception.class) | @Transactional(rollbackFor = Exception.class) | ||||
public synchronized void submitPurchaseNotice(SubmitPurchaseNoticeReq req) { | public synchronized void submitPurchaseNotice(SubmitPurchaseNoticeReq req) { | ||||
UserInfoDetails user = LoginUserUtil.userDetail(); | |||||
UserInfoDetails user = LoginUserUtil.userDetailNotNull(); | |||||
Long projectId = req.getProjectId(); | Long projectId = req.getProjectId(); | ||||
Project project = projectService.getNewestNoNull(projectId); | Project project = projectService.getNewestNoNull(projectId); | ||||
//首先要判断 项目当前状态 是不是 采购结果备案 | |||||
VUtils.isTrue(!ProjectStatus.TO_BE_PURCHASED.eq(project.getStatus()) | |||||
|| !ProjectStatus.PROJECT_APPROVED.eq(project.getStage())) | |||||
.throwMessage("提交失败,该项目不是待采购备案状态或者已立项阶段"); | |||||
List<MhPurchaseNoticeDTO> notices = new ArrayList<>(); | |||||
List<Purchase> purchases = req.getTenders().stream().map(w -> { | |||||
Purchase purchase = new Purchase(); | |||||
purchase.setPurchaseMethod(w.getPurchaseMethod()); | |||||
purchase.setBidAddress(w.getBidAddress()); | |||||
purchase.setBidName(w.getBidName()); | |||||
purchase.setBidBudget(w.getBidBudget()); | |||||
purchase.setBidDoc(w.getBidDoc()); | |||||
purchase.setBidStartTime(w.getBidStartTime()); | |||||
purchase.setBidEndTime(w.getBidEndTime()); | |||||
purchase.setId(w.getBidId()); | |||||
purchase.setProjectId(projectId); | |||||
purchase.setPurchaseConnectAddress(w.getPurchaseConnectAddress()); | |||||
purchase.setPurchasePhone(w.getPurchasePhone()); | |||||
purchase.setPurchaseRemark(w.getPurchaseRemark()); | |||||
purchase.setPurchaseScope(w.getPurchaseScope()); | |||||
purchase.setPurchaseUnit(w.getPurchaseUnit()); | |||||
purchase.setPurchaseUnitId(w.getPurchaseUnitId()); | |||||
purchase.setPurchaseContact(w.getPurchaseContact()); | |||||
purchase.setBidType(w.getBidType()); | |||||
purchase.setPurchaseDate(w.getPurchaseDate()); | |||||
purchase.setBidPayAmount(w.getBidPayAmount()); | |||||
purchase.setPublishMhNotice(w.getPublishMhNotice()); | |||||
if (purchase.getId() == null) { | |||||
purchase.setCreateBy(user.getUserIdStr()); | |||||
} | |||||
purchase.setStatus(TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO.getCode()); | |||||
purchase.setXcfhxApplyStatus(TenderXcfhxApplyStatus.TO_BE_SUBMIT_XCFHX_APPLY.getCode()); | |||||
if (Boolean.TRUE.equals(mhPurchaseNoticeOpen) && Boolean.TRUE.equals(w.getPublishMhNotice())) { | |||||
notices.add(buildPurchaseNotice(w, user)); | |||||
} | |||||
return purchase; | |||||
}).collect(Collectors.toList()); | |||||
purchaseService.saveOrUpdateBatch(purchases); | |||||
List<ProjectGovSystemReplaceInfos> projectGovSystemReplaceInfos = new ArrayList<>(); | |||||
for (int i = 0; i < req.getTenders().size(); i++) { | |||||
List<Long> systemReplaceInfoIds = req.getTenders().get(i).getSystemReplaceInfoIds(); | |||||
if (CollUtil.isNotEmpty(systemReplaceInfoIds)) { | |||||
Long bidId = purchases.get(i).getId(); | |||||
for (Long systemReplaceInfoId : systemReplaceInfoIds) { | |||||
ProjectGovSystemReplaceInfos replaceInfos = new ProjectGovSystemReplaceInfos(); | |||||
replaceInfos.setId(systemReplaceInfoId); | |||||
replaceInfos.setBidId(bidId); | |||||
projectGovSystemReplaceInfos.add(replaceInfos); | |||||
} | |||||
} | |||||
if (!ProjectStatus.TO_BE_PURCHASED.eq(project.getStatus())) { | |||||
throw ReturnException.wrap("项目状态错误,无法提交采购公告"); | |||||
} | } | ||||
projectGovSystemReplaceInfosService.updateBatchById(projectGovSystemReplaceInfos); | |||||
WflowModels wflowModels = processModelManage.getWflowModelsNoNull(ProjectProcessType.PURCHASE_NOTICE, user.getMhUnitId()); | |||||
List<Purchase> purchases = convertPurchase(req.getTenders(), projectId, user, TO_BE_SUBMIT_PURCHASE_NOTICE); | |||||
purchaseService.saveBatch(purchases); | |||||
savePurchaseInstRelation(purchases, user, project, wflowModels); | |||||
// 保存系统关联标段信息 | |||||
saveSystemInfoBidRelation(req, purchases); | |||||
projectStateMachineUtil.pass(project); | projectStateMachineUtil.pass(project); | ||||
projectService.updateById(project); | projectService.updateById(project); | ||||
SpringUtil.publishEvent(MhTodoHandedEvent.of(MHTodoTypeEnum.WITHOUT_PURCHASE_NOTICE, project.getId())); | |||||
stagingManage.delete(StagingType.PURCHASE_NOTICE, project.getProjectCode()); | |||||
} | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public synchronized void resubmitPurchaseNotice(SubmitPurchaseNoticeReq req) { | |||||
UserInfoDetails user = LoginUserUtil.userDetailNotNull(); | |||||
Long projectId = req.getProjectId(); | |||||
Project project = projectService.getNewestNoNull(projectId); | |||||
if (!ProjectStatus.ON_PURCHASING.eq(project.getStatus())) { | |||||
throw ReturnException.wrap("项目状态错误,无法提交采购公告"); | |||||
} | |||||
WflowModels wflowModels = processModelManage.getWflowModelsNoNull(ProjectProcessType.PURCHASE_NOTICE, user.getMhUnitId()); | |||||
List<Purchase> purchases = convertPurchase(req.getTenders(), projectId, null, PURCHASE_NOTICE_FAILED); | |||||
savePurchaseInstRelation(purchases, user, project, wflowModels); | |||||
purchaseService.updateBatchById(purchases); | |||||
// 保存系统关联标段信息 | |||||
saveSystemInfoBidRelation(req, purchases); | |||||
stagingManage.delete(StagingType.PURCHASE_NOTICE, project.getProjectCode()); | |||||
} | |||||
private void savePurchaseInstRelation(List<Purchase> purchases, UserInfoDetails user, Project project, WflowModels wflowModels) { | |||||
for (Purchase purchase : purchases) { | for (Purchase purchase : purchases) { | ||||
SpringUtil.publishEvent(MhTodoSendEvent.of(MHTodoTypeEnum.WITHOUT_PURCHASE_CONTRACT, project, purchase)); | |||||
tenderStateMachineUtil.pass(purchase); | |||||
} | } | ||||
// 发布采购公告 | |||||
if (!notices.isEmpty()) { | |||||
mhApiClient.publishPurchaseNotice(notices); | |||||
purchaseService.updateBatchById(purchases); | |||||
// 保存流程相关信息 | |||||
Map<String, OrgInfoDTO> orgModelMap = declaredProjectManage.buildOrgModelMap(user, project); | |||||
ProcessStartParamsVo processParam = new ProcessStartParamsVo(); | |||||
processParam.setUser(declaredProjectManage.buildUser(user)); | |||||
processParam.setProcessUsers(Collections.emptyMap()); | |||||
processParam.setFormData(Collections.emptyMap()); | |||||
for (Purchase purchase : purchases) { | |||||
String intCode = processInstanceService.startProcessLs(wflowModels, processParam, orgModelMap); | |||||
saveProjectPurchaseInstCode(purchase.getId(), intCode, project.getId(), ProjectProcessType.PURCHASE_NOTICE); | |||||
} | } | ||||
stagingManage.delete(StagingType.PURCHASE_NOTICE, project.getProjectCode()); | |||||
} | } | ||||
@Transactional(rollbackFor = Exception.class) | @Transactional(rollbackFor = Exception.class) | ||||
public synchronized void appendPurchaseNotice(SubmitPurchaseNoticeReq req) { | public synchronized void appendPurchaseNotice(SubmitPurchaseNoticeReq req) { | ||||
UserInfoDetails user = LoginUserUtil.userDetail(); | |||||
UserInfoDetails user = LoginUserUtil.userDetailNotNull(); | |||||
Long projectId = req.getProjectId(); | Long projectId = req.getProjectId(); | ||||
long purchaseCount = purchaseService.countByProjectId(projectId); | long purchaseCount = purchaseService.countByProjectId(projectId); | ||||
if (purchaseCount == 0) { | if (purchaseCount == 0) { | ||||
throw ReturnException.wrap("请先发布采购公告"); | throw ReturnException.wrap("请先发布采购公告"); | ||||
} | } | ||||
WflowModels wflowModels = processModelManage.getWflowModelsNoNull(ProjectProcessType.PURCHASE_NOTICE, user.getMhUnitId()); | |||||
req.getTenders().removeIf(w -> w.getBidId() != null); | req.getTenders().removeIf(w -> w.getBidId() != null); | ||||
Project project = projectService.getNewestNoNull(projectId); | Project project = projectService.getNewestNoNull(projectId); | ||||
List<MhPurchaseNoticeDTO> notices = new ArrayList<>(); | |||||
List<Purchase> purchases = req.getTenders().stream().map(w -> { | |||||
List<Purchase> purchases = convertPurchase(req.getTenders(), projectId, user, TO_BE_SUBMIT_PURCHASE_NOTICE); | |||||
purchaseService.saveBatch(purchases); | |||||
savePurchaseInstRelation(purchases, user, project, wflowModels); | |||||
saveSystemInfoBidRelation(req, purchases); | |||||
if (!ProjectStatus.ON_PURCHASING.eq(project.getStatus())) { | |||||
project.setStatus(ProjectStatus.ON_PURCHASING.getCode()); | |||||
project.setStage(ProjectStatus.ON_PURCHASING.getStage()); | |||||
projectService.updateById(project); | |||||
Wrapper<ProjectStatusChange> query = Wrappers.lambdaQuery(ProjectStatusChange.class) | |||||
.eq(ProjectStatusChange::getProjectCode, project.getProjectCode()) | |||||
.in(ProjectStatusChange::getEvent, | |||||
ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD, | |||||
ProjectStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM, | |||||
ProjectStateChangeEvent.SUBMIT_FIRST_INSPECTED_FILES, | |||||
ProjectStateChangeEvent.FINAL_ACCEPTANCE_APPLICATION, | |||||
ProjectStateChangeEvent.FINAL_ACCEPTANCE_PASS); | |||||
projectStatusChangeService.remove(query); | |||||
} | |||||
stagingManage.delete(StagingType.PURCHASE_NOTICE, project.getProjectCode()); | |||||
} | |||||
private static List<Purchase> convertPurchase(List<PurchaseNoticeTenderDTO> reqTenders, | |||||
Long projectId, | |||||
UserInfoDetails user, | |||||
TenderMainStatus status) { | |||||
List<Purchase> purchases = reqTenders.stream().map(w -> { | |||||
Purchase purchase = new Purchase(); | Purchase purchase = new Purchase(); | ||||
purchase.setPurchaseMethod(w.getPurchaseMethod()); | purchase.setPurchaseMethod(w.getPurchaseMethod()); | ||||
purchase.setBidAddress(w.getBidAddress()); | purchase.setBidAddress(w.getBidAddress()); | ||||
@@ -510,15 +526,16 @@ public class PurchaseManage { | |||||
purchase.setPurchaseDate(w.getPurchaseDate()); | purchase.setPurchaseDate(w.getPurchaseDate()); | ||||
purchase.setBidPayAmount(w.getBidPayAmount()); | purchase.setBidPayAmount(w.getBidPayAmount()); | ||||
purchase.setPublishMhNotice(w.getPublishMhNotice()); | purchase.setPublishMhNotice(w.getPublishMhNotice()); | ||||
purchase.setCreateBy(user.getUserIdStr()); | |||||
purchase.setStatus(TenderMainStatus.TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO.getCode()); | |||||
purchase.setXcfhxApplyStatus(TenderXcfhxApplyStatus.TO_BE_SUBMIT_XCFHX_APPLY.getCode()); | |||||
if (Boolean.TRUE.equals(mhPurchaseNoticeOpen) && Boolean.TRUE.equals(w.getPublishMhNotice())) { | |||||
notices.add(buildPurchaseNotice(w, user)); | |||||
if (w.getBidId() == null) { | |||||
purchase.setCreateBy(user.getUserIdStr()); | |||||
} | } | ||||
purchase.setStatus(status.getCode()); | |||||
return purchase; | return purchase; | ||||
}).collect(Collectors.toList()); | }).collect(Collectors.toList()); | ||||
purchaseService.saveBatch(purchases); | |||||
return purchases; | |||||
} | |||||
private void saveSystemInfoBidRelation(SubmitPurchaseNoticeReq req, List<Purchase> purchases) { | |||||
List<ProjectGovSystemReplaceInfos> projectGovSystemReplaceInfos = new ArrayList<>(); | List<ProjectGovSystemReplaceInfos> projectGovSystemReplaceInfos = new ArrayList<>(); | ||||
for (int i = 0; i < req.getTenders().size(); i++) { | for (int i = 0; i < req.getTenders().size(); i++) { | ||||
List<Long> systemReplaceInfoIds = req.getTenders().get(i).getSystemReplaceInfoIds(); | List<Long> systemReplaceInfoIds = req.getTenders().get(i).getSystemReplaceInfoIds(); | ||||
@@ -533,26 +550,6 @@ public class PurchaseManage { | |||||
} | } | ||||
} | } | ||||
projectGovSystemReplaceInfosService.updateBatchById(projectGovSystemReplaceInfos); | projectGovSystemReplaceInfosService.updateBatchById(projectGovSystemReplaceInfos); | ||||
project.setStatus(ProjectStatus.ON_PURCHASING.getCode()); | |||||
project.setStage(ProjectStatus.ON_PURCHASING.getStage()); | |||||
projectService.updateById(project); | |||||
Wrapper<ProjectStatusChange> query = Wrappers.lambdaQuery(ProjectStatusChange.class) | |||||
.eq(ProjectStatusChange::getProjectCode, project.getProjectCode()) | |||||
.in(ProjectStatusChange::getEvent, | |||||
ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD, | |||||
ProjectStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM, | |||||
ProjectStateChangeEvent.SUBMIT_FIRST_INSPECTED_FILES, | |||||
ProjectStateChangeEvent.FINAL_ACCEPTANCE_APPLICATION, | |||||
ProjectStateChangeEvent.FINAL_ACCEPTANCE_PASS); | |||||
projectStatusChangeService.remove(query); | |||||
for (Purchase purchase : purchases) { | |||||
SpringUtil.publishEvent(MhTodoSendEvent.of(MHTodoTypeEnum.WITHOUT_PURCHASE_CONTRACT, project, purchase)); | |||||
} | |||||
// 发布采购公告 | |||||
if (!notices.isEmpty()) { | |||||
mhApiClient.publishPurchaseNotice(notices); | |||||
} | |||||
stagingManage.delete(StagingType.PURCHASE_NOTICE, project.getProjectCode()); | |||||
} | } | ||||
public synchronized void pushToMhNotice(Long purchaseId) { | public synchronized void pushToMhNotice(Long purchaseId) { | ||||
@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||||
import com.baomidou.mybatisplus.extension.service.IService; | import com.baomidou.mybatisplus.extension.service.IService; | ||||
import com.hz.pm.api.common.util.BizUtils; | import com.hz.pm.api.common.util.BizUtils; | ||||
import com.hz.pm.api.projectdeclared.model.entity.PurchaseInst; | import com.hz.pm.api.projectdeclared.model.entity.PurchaseInst; | ||||
import com.hz.pm.api.projectlib.model.enumeration.InstTypeEnum; | |||||
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.Comparator; | import java.util.Comparator; | ||||
@@ -47,7 +46,7 @@ public interface IPurchaseInstService extends IService<PurchaseInst> { | |||||
return list(query); | return list(query); | ||||
} | } | ||||
default Map<Long, PurchaseInst> list(Collection<Long> purchaseIds, Integer instType) { | |||||
default Map<Long, PurchaseInst> listNewest(Collection<Long> purchaseIds, Integer instType) { | |||||
List<PurchaseInst> instances = list(Wrappers.lambdaQuery(PurchaseInst.class) | List<PurchaseInst> instances = list(Wrappers.lambdaQuery(PurchaseInst.class) | ||||
.in(PurchaseInst::getBidId, purchaseIds) | .in(PurchaseInst::getBidId, purchaseIds) | ||||
.eq(PurchaseInst::getInstType, instType)); | .eq(PurchaseInst::getInstType, instType)); | ||||
@@ -75,8 +75,7 @@ public class ProjectManageTodoCountManage { | |||||
futures.add(CompletableFuture.runAsync(() -> { | futures.add(CompletableFuture.runAsync(() -> { | ||||
// 招标采购 | // 招标采购 | ||||
PurchaseProgressStatVO purchaseStat = purchaseManage.purchaseProgressStatistics(new ProjectListReq()); | PurchaseProgressStatVO purchaseStat = purchaseManage.purchaseProgressStatistics(new ProjectListReq()); | ||||
todoCount.setProjectPurchase(sum(purchaseStat, PurchaseProgressStatVO::getToBePurchaseCount, | |||||
PurchaseProgressStatVO::getOnPurchaseCount)); | |||||
todoCount.setProjectPurchase(sum(purchaseStat, PurchaseProgressStatVO::getOnPurchaseCount)); | |||||
// 适配改造 | // 适配改造 | ||||
AdaptionProgressStatVO adaptionStat = purchaseManage.adaptionProgressStatistics(new PurchaseAdaptionListReq()); | AdaptionProgressStatVO adaptionStat = purchaseManage.adaptionProgressStatistics(new PurchaseAdaptionListReq()); | ||||
todoCount.setProjectAdaption(sum(adaptionStat, AdaptionProgressStatVO::getWithoutOperationCount, | todoCount.setProjectAdaption(sum(adaptionStat, AdaptionProgressStatVO::getWithoutOperationCount, | ||||
@@ -34,7 +34,8 @@ public enum InstTypeEnum { | |||||
COMPLIANCE_REVIEW(13, "合规性审查审批流程"), | COMPLIANCE_REVIEW(13, "合规性审查审批流程"), | ||||
PROJECT_REVIEW(14, "项目复核审批流程"), | PROJECT_REVIEW(14, "项目复核审批流程"), | ||||
PROJECT_STOPPED(15, "项目终止审批流程"), | PROJECT_STOPPED(15, "项目终止审批流程"), | ||||
PROJECT_CHANGE(16, "项目变更审批流程"); | |||||
PROJECT_CHANGE(16, "项目变更审批流程"), | |||||
PURCHASE_NOTICE(17, "采购公告审批流程"); | |||||
private Integer code; | private Integer code; | ||||
private String desc; | private String desc; | ||||
@@ -24,6 +24,10 @@ import java.util.stream.Stream; | |||||
@AllArgsConstructor | @AllArgsConstructor | ||||
public enum TenderMainStatus implements ITenderStatus { | public enum TenderMainStatus implements ITenderStatus { | ||||
TO_BE_SUBMIT_PURCHASE_NOTICE(ProjectStatus.ON_PURCHASING, 100, "待发布采购公告"), | |||||
ON_PURCHASE_NOTICE_APPLY(ProjectStatus.ON_PURCHASING, 107, "采购公告审核中"), | |||||
PURCHASE_NOTICE_FAILED(ProjectStatus.ON_PURCHASING, 108, "采购公告审核不通过"), | |||||
// | |||||
TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO(ProjectStatus.ON_PURCHASING, 101, "待填写采购&合同信息"), | TO_BE_SUBMIT_PURCHASE_CONSTRUCTION_INFO(ProjectStatus.ON_PURCHASING, 101, "待填写采购&合同信息"), | ||||
PURCHASE_FINISHED(ProjectStatus.ON_PURCHASING, 106, "采购完成"), | PURCHASE_FINISHED(ProjectStatus.ON_PURCHASING, 106, "采购完成"), | ||||
TO_BE_SUBMIT_OPERATION_PLAN(ProjectStatus.ON_ADAPTING, 103, "待填写实施计划"), | TO_BE_SUBMIT_OPERATION_PLAN(ProjectStatus.ON_ADAPTING, 103, "待填写实施计划"), | ||||
@@ -46,7 +50,7 @@ public enum TenderMainStatus implements ITenderStatus { | |||||
private final String desc; | private final String desc; | ||||
private static Optional<ITenderStatus> get(Integer status) { | |||||
public static Optional<ITenderStatus> get(Integer status) { | |||||
return Optional.ofNullable(TENDER_STATUS_MAP.get(status)); | return Optional.ofNullable(TENDER_STATUS_MAP.get(status)); | ||||
} | } | ||||
@@ -11,6 +11,7 @@ import com.hz.pm.api.external.model.dto.MhZwddWorkNoticeDTO; | |||||
import com.hz.pm.api.external.todo.MHTodoClient; | import com.hz.pm.api.external.todo.MHTodoClient; | ||||
import com.hz.pm.api.external.todo.dto.MhTodoExtraParamDTO; | import com.hz.pm.api.external.todo.dto.MhTodoExtraParamDTO; | ||||
import com.hz.pm.api.external.todo.enumerization.MHTodoTypeEnum; | import com.hz.pm.api.external.todo.enumerization.MHTodoTypeEnum; | ||||
import com.hz.pm.api.projectdeclared.manage.PurchaseManage; | |||||
import com.hz.pm.api.projectdeclared.model.entity.Purchase; | import com.hz.pm.api.projectdeclared.model.entity.Purchase; | ||||
import com.hz.pm.api.projectdeclared.model.entity.PurchaseInst; | import com.hz.pm.api.projectdeclared.model.entity.PurchaseInst; | ||||
import com.hz.pm.api.projectdeclared.model.entity.Xinchuang; | import com.hz.pm.api.projectdeclared.model.entity.Xinchuang; | ||||
@@ -71,6 +72,7 @@ public class UserTaskCreateOrFinishListener { | |||||
private final IXinchuangInstService xinchuangInstService; | private final IXinchuangInstService xinchuangInstService; | ||||
private final IXinchuangService xinchuangService; | private final IXinchuangService xinchuangService; | ||||
private final TaskService taskService; | private final TaskService taskService; | ||||
private final PurchaseManage purchaseManage; | |||||
private Instant instantDelay10s() { | private Instant instantDelay10s() { | ||||
return Instant.now().plusSeconds(10); | return Instant.now().plusSeconds(10); | ||||
@@ -92,7 +94,6 @@ public class UserTaskCreateOrFinishListener { | |||||
SCHEDULER.schedule(() -> { | SCHEDULER.schedule(() -> { | ||||
try { | try { | ||||
handleEvent(event); | handleEvent(event); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
log.error("任务节点完成监听异常:{}", event, e); | log.error("任务节点完成监听异常:{}", event, e); | ||||
} | } | ||||
@@ -122,6 +123,7 @@ public class UserTaskCreateOrFinishListener { | |||||
case PROJECT_STOPPED: | case PROJECT_STOPPED: | ||||
case COMPLIANCE_REVIEW: | case COMPLIANCE_REVIEW: | ||||
case PROJECT_REVIEW: | case PROJECT_REVIEW: | ||||
case PURCHASE_NOTICE: | |||||
// 发送信产平台待办 | // 发送信产平台待办 | ||||
MHTodoTypeEnum todoType = getMhTodoTypeEnum(procType); | MHTodoTypeEnum todoType = getMhTodoTypeEnum(procType); | ||||
MhTodoExtraParamDTO paramObj = MhTodoExtraParamDTO.builder() | MhTodoExtraParamDTO paramObj = MhTodoExtraParamDTO.builder() | ||||
@@ -136,7 +138,8 @@ public class UserTaskCreateOrFinishListener { | |||||
|| procType.equals(ProjectProcessType.ADAPTION) | || procType.equals(ProjectProcessType.ADAPTION) | ||||
|| procType.equals(ProjectProcessType.XC_APPROVAL_PROCESS) | || procType.equals(ProjectProcessType.XC_APPROVAL_PROCESS) | ||||
|| procType.equals(ProjectProcessType.TEST_VALID) | || procType.equals(ProjectProcessType.TEST_VALID) | ||||
|| procType.equals(ProjectProcessType.SELF_TEST)) { | |||||
|| procType.equals(ProjectProcessType.SELF_TEST) | |||||
|| procType.equals(ProjectProcessType.PURCHASE_NOTICE)) { | |||||
PurchaseInst purchaseInst = purchaseInstService.getByProjectIdAndInstCode(paramObj.getProjectId(), procInstId); | PurchaseInst purchaseInst = purchaseInstService.getByProjectIdAndInstCode(paramObj.getProjectId(), procInstId); | ||||
paramObj.setBidId(purchaseInst.getBidId()); | paramObj.setBidId(purchaseInst.getBidId()); | ||||
paramObj.setProjectId(purchaseInst.getProjectId()); | paramObj.setProjectId(purchaseInst.getProjectId()); | ||||
@@ -211,6 +214,7 @@ public class UserTaskCreateOrFinishListener { | |||||
case PROJECT_STOPPED: | case PROJECT_STOPPED: | ||||
case COMPLIANCE_REVIEW: | case COMPLIANCE_REVIEW: | ||||
case PROJECT_REVIEW: | case PROJECT_REVIEW: | ||||
case PURCHASE_NOTICE: | |||||
MHTodoTypeEnum todoType = getMhTodoTypeEnum(procType); | MHTodoTypeEnum todoType = getMhTodoTypeEnum(procType); | ||||
log.info("完成任务: {} 信产待办:{}", event.getTaskId(), todoType); | log.info("完成任务: {} 信产待办:{}", event.getTaskId(), todoType); | ||||
if (orUserTask) { | if (orUserTask) { | ||||
@@ -293,6 +297,12 @@ public class UserTaskCreateOrFinishListener { | |||||
} | } | ||||
mhTodoClient.addTodo(paramObj, userFullInfo, nextStep, bizId, todoMsg); | mhTodoClient.addTodo(paramObj, userFullInfo, nextStep, bizId, todoMsg); | ||||
} | } | ||||
// 审批通过之后发送信产待办 | |||||
if (procType.equals(ProjectProcessType.PURCHASE_NOTICE) | |||||
&& purchase != null | |||||
&& Boolean.TRUE.equals(purchase.getPublishMhNotice())) { | |||||
purchaseManage.pushToMhNotice(purchase.getId()); | |||||
} | |||||
} | } | ||||
break; | break; | ||||
default: | default: | ||||
@@ -341,6 +351,9 @@ public class UserTaskCreateOrFinishListener { | |||||
case ACCEPTANCE_DECLARATION_APPROVAL_PROCESS: | case ACCEPTANCE_DECLARATION_APPROVAL_PROCESS: | ||||
todoType = MHTodoTypeEnum.FINAL_INSPECT_AUDIT; | todoType = MHTodoTypeEnum.FINAL_INSPECT_AUDIT; | ||||
break; | break; | ||||
case PURCHASE_NOTICE: | |||||
todoType = MHTodoTypeEnum.PURCHASE_NOTICE_AUDIT; | |||||
break; | |||||
default: | default: | ||||
throw BizException.wrap("未知待办类型:" + procType); | throw BizException.wrap("未知待办类型:" + procType); | ||||
} | } | ||||
@@ -353,6 +366,7 @@ public class UserTaskCreateOrFinishListener { | |||||
case ADAPTION: | case ADAPTION: | ||||
case ACCEPTANCE_DECLARATION_APPROVAL_PROCESS: | case ACCEPTANCE_DECLARATION_APPROVAL_PROCESS: | ||||
case SELF_TEST: | case SELF_TEST: | ||||
case PURCHASE_NOTICE: | |||||
return Boolean.TRUE; | return Boolean.TRUE; | ||||
default: | default: | ||||
} | } | ||||
@@ -74,224 +74,11 @@ public class SysProcDefController { | |||||
return processModelService.deployProcessLs(formId, null); | return processModelService.deployProcessLs(formId, null); | ||||
} | } | ||||
@GetMapping("/initProcessForUnits") | |||||
@GetMapping("/initUnitProcess") | |||||
@PreAuthorize("hasAuthority('SUPER_ADMIN')") | @PreAuthorize("hasAuthority('SUPER_ADMIN')") | ||||
public void initProcessForUnits(@RequestParam Set<Long> unitIds) { | |||||
initProcessManage.initProcessForUnits(unitIds); | |||||
} | |||||
public static void main(String[] args) { | |||||
String s = "[{\n" + | |||||
" \"id\": 32,\n" + | |||||
" \"name\": \"上城区信创办\",\n" + | |||||
" \"parentId\": 1084,\n" + | |||||
" \"shortName\": \"上城区\",\n" + | |||||
" \"sort\": 13,\n" + | |||||
" \"type\": \"NODE\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3418,\n" + | |||||
" \"name\": \"上城区国有企业\",\n" + | |||||
" \"parentId\": 32,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 41,\n" + | |||||
" \"name\": \"临安区信创办\",\n" + | |||||
" \"parentId\": 1084,\n" + | |||||
" \"shortName\": \"临安区\",\n" + | |||||
" \"sort\": 4,\n" + | |||||
" \"type\": \"NODE\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3409,\n" + | |||||
" \"name\": \"临安区国有企业\",\n" + | |||||
" \"parentId\": 41,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 38,\n" + | |||||
" \"name\": \"临平区信创办\",\n" + | |||||
" \"parentId\": 1084,\n" + | |||||
" \"shortName\": \"临平区\",\n" + | |||||
" \"sort\": 7,\n" + | |||||
" \"type\": \"NODE\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3412,\n" + | |||||
" \"name\": \"临平区国有企业\",\n" + | |||||
" \"parentId\": 38,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 37,\n" + | |||||
" \"name\": \"余杭区信创办\",\n" + | |||||
" \"parentId\": 1084,\n" + | |||||
" \"shortName\": \"余杭区\",\n" + | |||||
" \"sort\": 8,\n" + | |||||
" \"type\": \"NODE\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3413,\n" + | |||||
" \"name\": \"余杭区国有企业\",\n" + | |||||
" \"parentId\": 37,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 40,\n" + | |||||
" \"name\": \"富阳区信创办\",\n" + | |||||
" \"parentId\": 1084,\n" + | |||||
" \"shortName\": \"富阳区\",\n" + | |||||
" \"sort\": 5,\n" + | |||||
" \"type\": \"NODE\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3410,\n" + | |||||
" \"name\": \"富阳区国有企业\",\n" + | |||||
" \"parentId\": 40,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 1,\n" + | |||||
" \"name\": \"市信创办\",\n" + | |||||
" \"parentId\": 0,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"REGION\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3269,\n" + | |||||
" \"name\": \"市属国有企业\",\n" + | |||||
" \"parentId\": 1,\n" + | |||||
" \"sort\": 3,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 44,\n" + | |||||
" \"name\": \"建德市信创办\",\n" + | |||||
" \"parentId\": 1084,\n" + | |||||
" \"shortName\": \"建德市\",\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"NODE\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3406,\n" + | |||||
" \"name\": \"建德市国有企业\",\n" + | |||||
" \"parentId\": 44,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 33,\n" + | |||||
" \"name\": \"拱墅区信创办\",\n" + | |||||
" \"parentId\": 1084,\n" + | |||||
" \"shortName\": \"拱墅区\",\n" + | |||||
" \"sort\": 12,\n" + | |||||
" \"type\": \"NODE\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3417,\n" + | |||||
" \"name\": \"拱墅区国有企业\",\n" + | |||||
" \"parentId\": 33,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 42,\n" + | |||||
" \"name\": \"桐庐县信创办\",\n" + | |||||
" \"parentId\": 1084,\n" + | |||||
" \"shortName\": \"桐庐县\",\n" + | |||||
" \"sort\": 3,\n" + | |||||
" \"type\": \"NODE\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3408,\n" + | |||||
" \"name\": \"桐庐县国有企业\",\n" + | |||||
" \"parentId\": 42,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 43,\n" + | |||||
" \"name\": \"淳安县信创办\",\n" + | |||||
" \"parentId\": 1084,\n" + | |||||
" \"shortName\": \"淳安县\",\n" + | |||||
" \"sort\": 2,\n" + | |||||
" \"type\": \"NODE\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3407,\n" + | |||||
" \"name\": \"淳安县国有企业\",\n" + | |||||
" \"parentId\": 43,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 35,\n" + | |||||
" \"name\": \"滨江区信创办\",\n" + | |||||
" \"parentId\": 1084,\n" + | |||||
" \"shortName\": \"滨江区\",\n" + | |||||
" \"sort\": 10,\n" + | |||||
" \"type\": \"NODE\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3415,\n" + | |||||
" \"name\": \"滨江区国有企业\",\n" + | |||||
" \"parentId\": 35,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 36,\n" + | |||||
" \"name\": \"萧山区信创办\",\n" + | |||||
" \"parentId\": 1084,\n" + | |||||
" \"shortName\": \"萧山区\",\n" + | |||||
" \"sort\": 9,\n" + | |||||
" \"type\": \"NODE\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3414,\n" + | |||||
" \"name\": \"萧山区国有企业\",\n" + | |||||
" \"parentId\": 36,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 34,\n" + | |||||
" \"name\": \"西湖区信创办\",\n" + | |||||
" \"parentId\": 1084,\n" + | |||||
" \"shortName\": \"西湖区\",\n" + | |||||
" \"sort\": 11,\n" + | |||||
" \"type\": \"NODE\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3416,\n" + | |||||
" \"name\": \"西湖区国有企业\",\n" + | |||||
" \"parentId\": 34,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 39,\n" + | |||||
" \"name\": \"钱塘区信创办\",\n" + | |||||
" \"parentId\": 1084,\n" + | |||||
" \"shortName\": \"钱塘区\",\n" + | |||||
" \"sort\": 6,\n" + | |||||
" \"type\": \"NODE\"\n" + | |||||
" },\n" + | |||||
" {\n" + | |||||
" \"id\": 3411,\n" + | |||||
" \"name\": \"钱塘区国有企业\",\n" + | |||||
" \"parentId\": 39,\n" + | |||||
" \"sort\": 1,\n" + | |||||
" \"type\": \"SASAC\"\n" + | |||||
" }\n" + | |||||
" ]"; | |||||
System.out.println(CollUtils.joinByComma(JSONUtil.toList(s, MhUnit.class), MhUnit::getId)); | |||||
public void initUnitProcess(@RequestParam Set<Long> unitIds, | |||||
@RequestParam(required = false) Integer processType) { | |||||
initProcessManage.initUnitProcess(unitIds, processType); | |||||
} | } | ||||
} | } |
@@ -32,19 +32,18 @@ import java.util.Set; | |||||
@RequiredArgsConstructor | @RequiredArgsConstructor | ||||
public class InitProcessManage { | public class InitProcessManage { | ||||
private final ProcessModelService processModelService; | private final ProcessModelService processModelService; | ||||
@Transactional(rollbackFor = Exception.class) | @Transactional(rollbackFor = Exception.class) | ||||
public synchronized void initProcessForUnits(Set<Long> unitIds) { | |||||
public synchronized void initUnitProcess(Set<Long> unitIds, Integer processType) { | |||||
if (CollUtil.isEmpty(unitIds)) { | if (CollUtil.isEmpty(unitIds)) { | ||||
return; | return; | ||||
} | } | ||||
List<String> strUnitIds = CollUtils.convert(unitIds, String::valueOf); | List<String> strUnitIds = CollUtils.convert(unitIds, String::valueOf); | ||||
ProjectProcessType[] stages = ProjectProcessType.values(); | |||||
List<WflowModels> allModels = processModelService.list(Wrappers.lambdaQuery(WflowModels.class) | List<WflowModels> allModels = processModelService.list(Wrappers.lambdaQuery(WflowModels.class) | ||||
.in(WflowModels::getRegionCode, strUnitIds)); | .in(WflowModels::getRegionCode, strUnitIds)); | ||||
Map<Integer, List<WflowModels>> modelsByType = CollUtils.group(allModels, WflowModels::getProcessType); | Map<Integer, List<WflowModels>> modelsByType = CollUtils.group(allModels, WflowModels::getProcessType); | ||||
ProjectProcessType[] stages = processType == null ? ProjectProcessType.values() : new ProjectProcessType[]{ProjectProcessType.getNoNull(processType)}; | |||||
for (ProjectProcessType stage : stages) { | for (ProjectProcessType stage : stages) { | ||||
List<WflowModels> currModels = modelsByType.getOrDefault(stage.getCode(), Collections.emptyList()); | List<WflowModels> currModels = modelsByType.getOrDefault(stage.getCode(), Collections.emptyList()); | ||||
Map<String, WflowModels> modelsByUnitId = CollUtils.listToMap(currModels, WflowModels::getRegionCode); | Map<String, WflowModels> modelsByUnitId = CollUtils.listToMap(currModels, WflowModels::getRegionCode); | ||||
@@ -5,7 +5,6 @@ import cn.hutool.core.date.DatePattern; | |||||
import cn.hutool.core.util.NumberUtil; | import cn.hutool.core.util.NumberUtil; | ||||
import com.alibaba.fastjson.JSON; | import com.alibaba.fastjson.JSON; | ||||
import com.baomidou.mybatisplus.core.conditions.Wrapper; | import com.baomidou.mybatisplus.core.conditions.Wrapper; | ||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | |||||
import com.baomidou.mybatisplus.core.toolkit.Assert; | import com.baomidou.mybatisplus.core.toolkit.Assert; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.google.common.collect.Sets; | import com.google.common.collect.Sets; | ||||
@@ -15,7 +14,6 @@ import com.hz.pm.api.common.model.constant.BizConst; | |||||
import com.hz.pm.api.common.model.constant.TypeReferenceConst; | import com.hz.pm.api.common.model.constant.TypeReferenceConst; | ||||
import com.hz.pm.api.common.statemachine.event.ProjectStateChangeEvent; | import com.hz.pm.api.common.statemachine.event.ProjectStateChangeEvent; | ||||
import com.hz.pm.api.common.statemachine.util.*; | import com.hz.pm.api.common.statemachine.util.*; | ||||
import com.hz.pm.api.common.util.BizUtils; | |||||
import com.hz.pm.api.filemanage.model.entity.ProjectApplyBorrow; | import com.hz.pm.api.filemanage.model.entity.ProjectApplyBorrow; | ||||
import com.hz.pm.api.filemanage.service.INdProjectApplyBorrowService; | import com.hz.pm.api.filemanage.service.INdProjectApplyBorrowService; | ||||
import com.hz.pm.api.projectdeclared.manage.DeclaredProjectManage; | import com.hz.pm.api.projectdeclared.manage.DeclaredProjectManage; | ||||
@@ -316,35 +314,38 @@ public class HandlerManage { | |||||
} | } | ||||
private void purchasePassedCallback(Project project, String instanceId, ProjectProcessType processStage) { | private void purchasePassedCallback(Project project, String instanceId, ProjectProcessType processStage) { | ||||
// 查询所有的标段 | |||||
List<Purchase> purchases = purchaseService.list(Wrappers.lambdaQuery(Purchase.class) | |||||
.eq(Purchase::getProjectId, project.getId()) | |||||
.eq(Purchase::getBidType, BidTypeEnum.BUILD_APP.getCode())); | |||||
Map<Long, Purchase> purchaseMap = CollUtils.listToMap(purchases, Purchase::getId); | |||||
// 查询所有标段对应的最新的信创审批流程编码 | |||||
List<PurchaseInst> instList = purchaseInstService.list(Wrappers.lambdaQuery(PurchaseInst.class) | |||||
.in(PurchaseInst::getBidId, purchaseMap.keySet()) | |||||
.eq(PurchaseInst::getInstType, processStage.getCode())); | |||||
Purchase currPurchase = instList.stream() | |||||
.filter(w -> w.getInstCode().equals(instanceId)) | |||||
.findFirst() | |||||
.flatMap(w -> Optional.ofNullable(purchaseMap.get(w.getBidId()))) | |||||
.orElseThrow(() -> BizException.wrap("当前审批的标段不存在")); | |||||
Purchase currPurchase; | |||||
if (!ProjectProcessType.PURCHASE_NOTICE.equals(processStage)) { | |||||
// 查询所有的标段 | |||||
Wrapper<Purchase> query = Wrappers.lambdaQuery(Purchase.class) | |||||
.eq(Purchase::getProjectId, project.getId()) | |||||
.eq(Purchase::getBidType, BidTypeEnum.BUILD_APP.getCode()); | |||||
List<Purchase> purchases = purchaseService.list(query); | |||||
Map<Long, Purchase> purchaseMap = CollUtils.listToMap(purchases, Purchase::getId); | |||||
// 查询所有标段对应的最新的信创审批流程编码 | |||||
Map<Long, PurchaseInst> purchaseInstMap = purchaseInstService.listNewest(purchaseMap.keySet(), processStage.getCode()); | |||||
currPurchase = purchaseInstMap.entrySet().stream() | |||||
.filter(w -> w.getValue().getInstCode().equals(instanceId)) | |||||
.findFirst() | |||||
.flatMap(w -> Optional.ofNullable(purchaseMap.get(w.getKey()))) | |||||
.orElseThrow(() -> BizException.wrap("当前审批的标段不存在")); | |||||
Set<String> instCodes = CollUtils.fieldSet(purchaseInstMap.values(), PurchaseInst::getInstCode); | |||||
if (instCodes.size() != purchases.size()) { | |||||
return; | |||||
} | |||||
if (wflowHelper.allInstancesFinished(instCodes)) { | |||||
projectStateMachineUtil.pass(project); | |||||
projectService.updateById(project); | |||||
} | |||||
} else { | |||||
PurchaseInst purchaseInst = purchaseInstService.getByInstCode(instanceId); | |||||
currPurchase = purchaseService.getById(purchaseInst.getBidId()); | |||||
Assert.notNull(currPurchase, "标段信息不存在"); | |||||
} | |||||
tenderStateMachineUtil.pass(currPurchase); | tenderStateMachineUtil.pass(currPurchase); | ||||
purchaseService.updateById(currPurchase); | purchaseService.updateById(currPurchase); | ||||
Collection<PurchaseInst> lastInstList = BizUtils.groupFirst(instList, PurchaseInst::getBidId, | |||||
Comparator.comparing(PurchaseInst::getCreateOn).reversed()); | |||||
Set<String> instCodes = CollUtils.fieldSet(lastInstList, PurchaseInst::getInstCode); | |||||
if (instCodes.size() != purchases.size()) { | |||||
return; | |||||
} | |||||
if (wflowHelper.allInstancesFinished(instCodes)) { | |||||
projectStateMachineUtil.pass(project); | |||||
projectService.updateById(project); | |||||
} | |||||
} | } | ||||
private void purchaseRejectedCallback(Project project, String instanceId) { | private void purchaseRejectedCallback(Project project, String instanceId) { | ||||
@@ -433,6 +434,7 @@ public class HandlerManage { | |||||
InstTypeEnum instTypeEnum = InstTypeEnum.getNoNull(instType); | InstTypeEnum instTypeEnum = InstTypeEnum.getNoNull(instType); | ||||
switch (instTypeEnum) { | switch (instTypeEnum) { | ||||
case PROJECT_FINAL_INSPECTION: | case PROJECT_FINAL_INSPECTION: | ||||
case PURCHASE_NOTICE: | |||||
purchaseRejectedCallback(project, instanceId); | purchaseRejectedCallback(project, instanceId); | ||||
break; | break; | ||||
case XCFHX_APPLY: | case XCFHX_APPLY: | ||||
@@ -319,15 +319,15 @@ public class FlowableTest extends AppTests { | |||||
private MhUnitManage mhUnitManage; | private MhUnitManage mhUnitManage; | ||||
@Test | @Test | ||||
public void test1(){ | |||||
public void test1() { | |||||
List<MhUnitTreeDTO> units = mhUnitManage.getMhUnitDashboardOption(); | List<MhUnitTreeDTO> units = mhUnitManage.getMhUnitDashboardOption(); | ||||
Set<Long> unitIds = CollUtils.fieldSet(units, MhUnitTreeDTO::getId); | Set<Long> unitIds = CollUtils.fieldSet(units, MhUnitTreeDTO::getId); | ||||
initProcessManage.initProcessForUnits(unitIds); | |||||
initProcessManage.initUnitProcess(unitIds, null); | |||||
} | } | ||||
@Test | @Test | ||||
public void test() { | public void test() { | ||||
System.out.println(wflowHelper.isOrUserTask("9c05e0a3-e045-11ee-8427-02426daa406d","")); | |||||
System.out.println(wflowHelper.isOrUserTask("9c05e0a3-e045-11ee-8427-02426daa406d", "")); | |||||
} | } | ||||
} | } |