diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpAfterSalesController.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpAfterSalesController.java index d452016c..0ef6d794 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpAfterSalesController.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpAfterSalesController.java @@ -113,4 +113,15 @@ public class ErpAfterSalesController extends BaseController { return R.ok(list); } + /** + * 提交项目售后信息并提交流程 + */ + @SaCheckPermission("oa/erp:afterSales:add") + @Log(title = "项目售后信息", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/submitAndFlowStart") + public R submitAndFlowStart(@Validated(AddGroup.class) @RequestBody ErpAfterSalesBo bo) { + return R.ok(erpAfterSalesService.submitAndFlowStart(bo)); + } + } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpBudgetInfoController.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpBudgetInfoController.java index 6a94e7e6..5b3c352a 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpBudgetInfoController.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpBudgetInfoController.java @@ -101,6 +101,17 @@ public class ErpBudgetInfoController extends BaseController { return toAjax(erpBudgetInfoService.updateByBo(bo)); } + /** + * 变更项目预算 + */ + @SaCheckPermission("oa:erp/budgetInfo:change") + @Log(title = "项目预算", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PostMapping("/change") + public R change(@Validated(AddGroup.class) @RequestBody ErpBudgetInfoBo bo) { + return toAjax(erpBudgetInfoService.changeByBo(bo)); + } + /** * 删除项目预算 * diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectReportDetailController.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectReportDetailController.java index bae7f664..6c55eff3 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectReportDetailController.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectReportDetailController.java @@ -15,7 +15,11 @@ import org.dromara.common.log.enums.BusinessType; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.web.core.BaseController; +import org.dromara.oa.erp.domain.bo.ErpContractInfoBo; +import org.dromara.oa.erp.domain.bo.ErpProjectReportBo; import org.dromara.oa.erp.domain.bo.ErpProjectReportDetailBo; +import org.dromara.oa.erp.domain.bo.ProjectReportAndDetailWrapperBo; +import org.dromara.oa.erp.domain.vo.ErpContractInfoVo; import org.dromara.oa.erp.domain.vo.ErpProjectReportDetailVo; import org.dromara.oa.erp.service.IErpProjectReportDetailService; import org.springframework.validation.annotation.Validated; @@ -114,4 +118,18 @@ public class ErpProjectReportDetailController extends BaseController { return R.ok(list); } + /** + * 提交合同信息并提交流程 + * @param wrapper + * @return + */ + @SaCheckPermission("oa/erp:projectReportDetail:add") + @Log(title = "项目周报明细", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/projectReportSubmitAndFlowStart") + public R projectReportSubmitAndFlowStart(@Validated(AddGroup.class) @RequestBody ProjectReportAndDetailWrapperBo wrapper) { + ErpProjectReportBo projectReport = wrapper.getProjectReport(); + ErpProjectReportDetailBo projectDetailReport = wrapper.getProjectDetailReport(); + return R.ok(erpProjectReportDetailService.projectReportSubmitAndFlowStart(projectReport, projectDetailReport)); + } } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpBudgetInfo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpBudgetInfo.java index 80be3a8d..3ebdb88b 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpBudgetInfo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpBudgetInfo.java @@ -42,7 +42,7 @@ public class ErpBudgetInfo extends TenantEntity { /** * 版本,新版本+1 */ - private Long budgetVersion; + private Integer budgetVersion; /** * 冗余,项目类别(1销售 2研发 3预投) diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectReport.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectReport.java index 1ac85c87..8f8f070d 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectReport.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectReport.java @@ -1,9 +1,6 @@ package org.dromara.oa.erp.domain; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableLogic; -import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.EqualsAndHashCode; import org.dromara.common.tenant.core.TenantEntity; @@ -27,7 +24,7 @@ public class ErpProjectReport extends TenantEntity { /** * 项目周报ID */ - @TableId(value = "report_id", type = IdType.AUTO) + @TableId(value = "report_id", type = IdType.ASSIGN_ID) private Long reportId; /** @@ -101,5 +98,27 @@ public class ErpProjectReport extends TenantEntity { */ private String projectCode; + /** + * 部门名称 + */ + @TableField(exist = false) + private String deptName; + /** + * 项目经理名称 + */ + @TableField(exist = false) + private String managerName; + + /** + * 部门负责人名称 + */ + @TableField(exist = false) + private String chargeName; + + /** + * 分管副总名称 + */ + @TableField(exist = false) + private String deputyName; } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectReportDetail.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectReportDetail.java index 3dbfde35..8b7bb2a9 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectReportDetail.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectReportDetail.java @@ -28,7 +28,7 @@ public class ErpProjectReportDetail extends TenantEntity { /** * 项目周报明细ID */ - @TableId(value = "report_detail_id", type = IdType.AUTO) + @TableId(value = "report_detail_id", type = IdType.ASSIGN_ID) private Long reportDetailId; /** diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpAfterSalesBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpAfterSalesBo.java index 3da4e06d..d45df539 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpAfterSalesBo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpAfterSalesBo.java @@ -13,10 +13,12 @@ import java.math.BigDecimal; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; import java.util.List; // 1. 别忘了导包 List +import java.util.Map; // 2. 导入两个子表的 BO 对象,因为前端传的是子表的业务数据 import org.dromara.oa.erp.domain.bo.ErpAfterSalesLaborCostsBo; import org.dromara.oa.erp.domain.bo.ErpAfterSalesMaterialCostsBo; +import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt; /** * 项目售后信息业务对象 erp_after_sales @@ -180,5 +182,20 @@ public class ErpAfterSalesBo extends BaseEntity { */ private List materialCostsList; + /** + * 流程定义编码 + */ + private String flowCode; + + /** + * 流程变量 前端会提交一个元素{'entity': {业务详情数据对象}} + */ + private Map variables; + + /** + * 业务扩展参数 + */ + private RemoteFlowInstanceBizExt bizExt; + } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpBudgetInfoBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpBudgetInfoBo.java index e3fbcdaf..3b99509b 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpBudgetInfoBo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpBudgetInfoBo.java @@ -44,7 +44,7 @@ public class ErpBudgetInfoBo extends BaseEntity { /** * 版本,新版本+1 */ - private Long budgetVersion; + private Integer budgetVersion; /** * 冗余,项目类别(1销售 2研发 3预投) diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectReportBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectReportBo.java index 4ee92d8a..92209544 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectReportBo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectReportBo.java @@ -1,5 +1,6 @@ package org.dromara.oa.erp.domain.bo; +import cn.idev.excel.annotation.ExcelProperty; import io.github.linpeilie.annotations.AutoMapper; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -90,5 +91,23 @@ public class ErpProjectReportBo extends BaseEntity { */ private String projectCode; + /** + * 部门名称 + */ + private String deptName; + /** + * 项目经理名称 + */ + private String managerName; + + /** + * 部门负责人名称 + */ + private String chargeName; + + /** + * 分管副总名称 + */ + private String deputyName; } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectReportDetailBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectReportDetailBo.java index b8b1a14c..c66444f7 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectReportDetailBo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectReportDetailBo.java @@ -1,5 +1,6 @@ package org.dromara.oa.erp.domain.bo; +import cn.hutool.core.util.ObjectUtil; import io.github.linpeilie.annotations.AutoMapper; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -7,8 +8,12 @@ import lombok.EqualsAndHashCode; import org.dromara.common.core.validate.EditGroup; import org.dromara.common.mybatis.core.domain.BaseEntity; import org.dromara.oa.erp.domain.ErpProjectReportDetail; +import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt; import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; /** * 项目周报明细业务对象 erp_project_report_detail @@ -96,6 +101,10 @@ public class ErpProjectReportDetailBo extends BaseEntity { * 流程状态 */ private String flowStatus; + /** + * 流程定义编码 + */ + private String flowCode; /** * 排序号 @@ -127,5 +136,49 @@ public class ErpProjectReportDetailBo extends BaseEntity { */ private String activeFlag; + /** + * 流程变量,前端会提交一个元素{'entity': {业务详情数据对象}} + */ + private Map variables; + + /** + * 流程业务扩展信息 + */ + private RemoteFlowInstanceBizExt bizExt; + /** + * 部门名称 + */ + private String deptName; + + /** + * 项目经理名称 + */ + private String managerName; + + /** + * 部门负责人名称 + */ + private String chargeName; + + /** + * 分管副总名称 + */ + private String deputyName; + + public Map getVariables() { + if (variables == null) { + return new HashMap<>(16); + } + variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue())); + return variables; + } + + public RemoteFlowInstanceBizExt getBizExt() { + if (ObjectUtil.isNull(bizExt)) { + bizExt = new RemoteFlowInstanceBizExt(); + } + return bizExt; + } + } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ProjectReportAndDetailWrapperBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ProjectReportAndDetailWrapperBo.java new file mode 100644 index 00000000..5db6429a --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ProjectReportAndDetailWrapperBo.java @@ -0,0 +1,12 @@ +package org.dromara.oa.erp.domain.bo; +import jakarta.validation.Valid; +import lombok.Data; + +@Data +public class ProjectReportAndDetailWrapperBo { + @Valid + private ErpProjectReportBo projectReport; + + @Valid + private ErpProjectReportDetailBo projectDetailReport; +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpBudgetInfoVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpBudgetInfoVo.java index 42bc357f..4839c374 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpBudgetInfoVo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpBudgetInfoVo.java @@ -51,7 +51,7 @@ public class ErpBudgetInfoVo implements Serializable { * 版本,新版本+1 */ @ExcelProperty(value = "版本,新版本+1") - private Long budgetVersion; + private Integer budgetVersion; /** * 冗余,项目类别(1销售 2研发 3预投) diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectReportDetailVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectReportDetailVo.java index ebe169a0..40c1e09e 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectReportDetailVo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectReportDetailVo.java @@ -155,5 +155,28 @@ public class ErpProjectReportDetailVo implements Serializable { @ExcelDictFormat(readConverterExp = "1=是,0=否") private String activeFlag; + /** + * 部门名称 + */ + @ExcelProperty(value = "部门名称") + private String deptName; + + /** + * 项目经理名称 + */ + @ExcelProperty(value = "项目经理名称") + private String managerName; + + /** + * 部门负责人名称 + */ + @ExcelProperty(value = "部门负责人名称") + private String chargeName; + + /** + * 分管副总名称 + */ + @ExcelProperty(value = "分管副总名称") + private String deputyName; } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectReportVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectReportVo.java index e449f6bd..7c51f5a9 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectReportVo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectReportVo.java @@ -6,6 +6,7 @@ import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import org.dromara.common.excel.annotation.ExcelDictFormat; import org.dromara.common.excel.convert.ExcelDictConvert; +import org.dromara.common.mybatis.core.domain.BaseEntity; import org.dromara.oa.erp.domain.ErpProjectReport; import java.io.Serial; @@ -21,7 +22,7 @@ import java.io.Serializable; @Data @ExcelIgnoreUnannotated @AutoMapper(target = ErpProjectReport.class) -public class ErpProjectReportVo implements Serializable { +public class ErpProjectReportVo extends BaseEntity implements Serializable { @Serial private static final long serialVersionUID = 1L; @@ -29,13 +30,13 @@ public class ErpProjectReportVo implements Serializable { /** * 项目周报ID */ - @ExcelProperty(value = "项目周报ID") +// @ExcelProperty(value = "项目周报ID") private Long reportId; /** * 项目ID */ - @ExcelProperty(value = "项目ID") +// @ExcelProperty(value = "项目ID") private Long projectId; /** @@ -43,6 +44,11 @@ public class ErpProjectReportVo implements Serializable { */ @ExcelProperty(value = "项目名称") private String projectName; + /** + * 项目编码 + */ + @ExcelProperty(value = "项目编码") + private String projectCode; /** * 当前里程碑 @@ -53,70 +59,27 @@ public class ErpProjectReportVo implements Serializable { /** * 项目经理 */ - @ExcelProperty(value = "项目经理") +// @ExcelProperty(value = "项目经理") private Long managerId; /** * 部门ID */ - @ExcelProperty(value = "部门ID") +// @ExcelProperty(value = "部门ID") private Long deptId; /** * 部门负责人 */ - @ExcelProperty(value = "部门负责人") +// @ExcelProperty(value = "部门负责人") private Long chargeId; /** * 分管副总 */ - @ExcelProperty(value = "分管副总") +// @ExcelProperty(value = "分管副总") private Long deputyId; - /** - * 周报情况说明 - */ - @ExcelProperty(value = "周报情况说明") - private String informationNote; - - /** - * 排序号 - */ - @ExcelProperty(value = "排序号") - private Long sortOrder; - - /** - * 附件ID(预留) - */ - @ExcelProperty(value = "附件ID", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "预=留") - private String ossId; - - /** - * 备注 - */ - @ExcelProperty(value = "备注") - private String remark; - - /** - * 激活标识(1是 0否) - */ - @ExcelProperty(value = "激活标识", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "1=是,0=否") - private String activeFlag; - - /** - * 项目编码 - */ - @ExcelProperty(value = "项目编码") - private String projectCode; - /** - * 项目类型名称 - */ - @ExcelProperty(value = "项目类型名称") - private String typeName; - /** * 部门名称 */ @@ -140,5 +103,43 @@ public class ErpProjectReportVo implements Serializable { */ @ExcelProperty(value = "分管副总名称") private String deputyName; + /** + * 周报情况说明 + */ + @ExcelProperty(value = "周报情况说明") + private String informationNote; + + /** + * 排序号 + */ +// @ExcelProperty(value = "排序号") + private Long sortOrder; + + /** + * 附件ID(预留) + */ + @ExcelProperty(value = "附件ID", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "预=留") + private String ossId; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 激活标识(1是 0否) + */ + @ExcelProperty(value = "激活标识", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "1=是,0=否") + private String activeFlag; + + /** + * 项目类型名称 + */ +// @ExcelProperty(value = "项目类型名称") + private String typeName; + } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectReportMapper.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectReportMapper.java index 7cde812d..44a4fbac 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectReportMapper.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectReportMapper.java @@ -45,4 +45,8 @@ public interface ErpProjectReportMapper extends BaseMapperPlus selectCustomErpProjectReportVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + public ErpProjectReportVo selectVoAndUserById(@Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + public List selectVoAndUserList(@Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpAfterSalesService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpAfterSalesService.java index 386b5e46..6c4418f2 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpAfterSalesService.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpAfterSalesService.java @@ -66,4 +66,12 @@ public interface IErpAfterSalesService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 提交售后信息并启动流程 + * @param bo + * @return + */ + ErpAfterSalesVo submitAndFlowStart(ErpAfterSalesBo bo); + } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpBudgetInfoService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpBudgetInfoService.java index 52b8152f..30fea8ba 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpBudgetInfoService.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpBudgetInfoService.java @@ -58,6 +58,14 @@ public interface IErpBudgetInfoService { */ Boolean updateByBo(ErpBudgetInfoBo bo); + /** + * 变更项目预算 + * + * @param bo 项目预算 + * @return 是否修改成功 + */ + Boolean changeByBo(ErpBudgetInfoBo bo); + /** * 校验并批量删除项目预算信息 * diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectReportDetailService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectReportDetailService.java index ebc7b758..eddfdd78 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectReportDetailService.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectReportDetailService.java @@ -2,7 +2,11 @@ package org.dromara.oa.erp.service; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.oa.erp.domain.bo.ErpContractInfoBo; +import org.dromara.oa.erp.domain.bo.ErpProjectReportBo; import org.dromara.oa.erp.domain.bo.ErpProjectReportDetailBo; +import org.dromara.oa.erp.domain.bo.ProjectReportAndDetailWrapperBo; +import org.dromara.oa.erp.domain.vo.ErpContractInfoVo; import org.dromara.oa.erp.domain.vo.ErpProjectReportDetailVo; import java.util.Collection; @@ -65,4 +69,11 @@ public interface IErpProjectReportDetailService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 提交项目周报并提交流程 + * @param + * @return + */ + ErpProjectReportDetailVo projectReportSubmitAndFlowStart(ErpProjectReportBo projectReport, ErpProjectReportDetailBo projectDetailReport); } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpAfterSalesServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpAfterSalesServiceImpl.java index afd8fe6c..0e6e3554 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpAfterSalesServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpAfterSalesServiceImpl.java @@ -1,6 +1,12 @@ package org.dromara.oa.erp.service.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.convert.Convert; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; +import org.apache.seata.spring.annotation.GlobalTransactional; +import org.dromara.common.core.enums.BusinessStatusEnum; +import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.TableDataInfo; @@ -10,6 +16,7 @@ import com.github.yulichang.toolkit.JoinWrappers; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; +import org.dromara.common.tenant.helper.TenantHelper; import org.dromara.oa.erp.domain.ErpAfterSalesLaborCosts; import org.dromara.oa.erp.domain.ErpAfterSalesMaterialCosts; import org.dromara.oa.erp.domain.bo.ErpAfterSalesLaborCostsBo; @@ -18,6 +25,8 @@ import org.dromara.oa.erp.domain.vo.ErpAfterSalesLaborCostsVo; import org.dromara.oa.erp.domain.vo.ErpAfterSalesMaterialCostsVo; import org.dromara.oa.erp.service.IErpAfterSalesLaborCostsService; import org.dromara.oa.erp.service.IErpAfterSalesMaterialCostsService; +import org.dromara.workflow.api.RemoteWorkflowService; +import org.dromara.workflow.api.domain.RemoteStartProcess; import org.springframework.stereotype.Service; import org.dromara.oa.erp.domain.bo.ErpAfterSalesBo; import org.dromara.oa.erp.domain.vo.ErpAfterSalesVo; @@ -26,7 +35,12 @@ import org.dromara.oa.erp.mapper.ErpAfterSalesMapper; import org.dromara.oa.erp.service.IErpAfterSalesService; import org.springframework.transaction.annotation.Transactional; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.springframework.context.event.EventListener; +import org.dromara.workflow.api.event.ProcessEvent; + + +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Collection; @@ -39,12 +53,14 @@ import java.util.Collection; */ @RequiredArgsConstructor @Service +@Slf4j public class ErpAfterSalesServiceImpl implements IErpAfterSalesService { private final ErpAfterSalesMapper baseMapper; - // 【修改点 1】注入两个子表的 Service - // 注意:这里必须加 final,配合 @RequiredArgsConstructor 使用 + @DubboReference(timeout = 30000) + private RemoteWorkflowService remoteWorkflowService; + private final IErpAfterSalesLaborCostsService laborCostsService; private final IErpAfterSalesMaterialCostsService materialCostsService; @@ -56,31 +72,21 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService { */ @Override public ErpAfterSalesVo queryById(Long afterSalesId){ - // 1. 查询主表 VO ErpAfterSalesVo vo = baseMapper.selectVoById(afterSalesId); - // 2. 如果主表存在,继续查询子表 if (vo != null) { - // ============ 处理人工费 ============ - // 2.1 使用 list 方法查询出 Entity 列表 List laborEntities = laborCostsService.list( new LambdaQueryWrapper() .eq(ErpAfterSalesLaborCosts::getAfterSalesId, afterSalesId) ); - // 2.2 将 Entity 列表转换为 VO 列表 (核心修复点) List laborVos = MapstructUtils.convert(laborEntities, ErpAfterSalesLaborCostsVo.class); - // 2.3 塞入主表对象 vo.setLaborCostsList(laborVos); - // ============ 处理材料费 ============ - // 3.1 使用 list 方法查询出 Entity 列表 List materialEntities = materialCostsService.list( new LambdaQueryWrapper() .eq(ErpAfterSalesMaterialCosts::getAfterSalesId, afterSalesId) ); - // 3.2 将 Entity 列表转换为 VO 列表 List materialVos = MapstructUtils.convert(materialEntities, ErpAfterSalesMaterialCostsVo.class); - // 3.3 塞入主表对象 vo.setMaterialCostsList(materialVos); } return vo; @@ -155,35 +161,23 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService { @Override @Transactional(rollbackFor = Exception.class) // 【重要】开启事务!如果子表保存失败,主表也要回滚,防止数据不一致 public Boolean insertByBo(ErpAfterSalesBo bo) { - // 1. 将 BO (业务对象) 转换为 Entity (数据库实体) - // MapstructUtils 是 Plus 封装的高性能 Bean 拷贝工具 ErpAfterSales add = MapstructUtils.convert(bo, ErpAfterSales.class); - // 2. 校验数据(这是生成的代码自带的) validEntityBeforeSave(add); - // 3. 保存主表 - // baseMapper.insert(add) 返回受影响行数,大于0表示成功 - // 成功后,MyBatis 会自动把生成的 ID 回填到 add 对象中 boolean flag = baseMapper.insert(add) > 0; + bo.setAfterSalesId(add.getAfterSalesId()); // 将生成的 ID 回填给 BO - // 4. 如果主表保存成功,开始处理子表 if (flag) { - Long afterSalesId = add.getAfterSalesId(); // 拿到主表刚才生成的 ID + Long afterSalesId = add.getAfterSalesId(); - // --- 处理子表 A:人员费用 --- List laborBoList = bo.getLaborCostsList(); - // 使用 CollUtil.isNotEmpty 判断列表不为空 if (CollUtil.isNotEmpty(laborBoList)) { - // 将 BO 列表转为 Entity 列表 List laborList = MapstructUtils.convert(laborBoList, ErpAfterSalesLaborCosts.class); - // 遍历每个子对象,把主表 ID 填进去,建立外键关联 laborList.forEach(item -> item.setAfterSalesId(afterSalesId)); - // 批量保存 laborCostsService.saveBatch(laborList); } - // --- 处理子表 B:材料费用 --- List materialBoList = bo.getMaterialCostsList(); if (CollUtil.isNotEmpty(materialBoList)) { List materialList = MapstructUtils.convert(materialBoList, ErpAfterSalesMaterialCosts.class); @@ -203,17 +197,14 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService { @Override @Transactional(rollbackFor = Exception.class) // 【重要】开启事务 public Boolean updateByBo(ErpAfterSalesBo bo) { - // 1. 更新主表数据 ErpAfterSales update = MapstructUtils.convert(bo, ErpAfterSales.class); validEntityBeforeSave(update); - // updateById 会根据主键 ID 更新其他字段 int row = baseMapper.updateById(update); - // 2. 如果主表更新成功,开始处理子表 if (row > 0) { Long afterSalesId = bo.getAfterSalesId(); - // ================== 1. 处理人员费用 ================== + // ================== 处理人员费用 ================== // 先删除旧的 laborCostsService.remove(new LambdaQueryWrapper() .eq(ErpAfterSalesLaborCosts::getAfterSalesId, afterSalesId)); @@ -223,7 +214,7 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService { if (CollUtil.isNotEmpty(laborBoList)) { List laborList = MapstructUtils.convert(laborBoList, ErpAfterSalesLaborCosts.class); - // 【核心修改点 👇】遍历列表,清空 ID + // 遍历列表,清空 ID laborList.forEach(item -> { item.setLaborCostsId(null); // 关键:清空ID,让MP重新生成雪花ID,避免和逻辑删除的数据冲突 item.setAfterSalesId(afterSalesId); @@ -232,17 +223,14 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService { laborCostsService.saveBatch(laborList); } - // ================== 2. 处理材料费用 ================== - // 先删除旧的 + // ================== 处理材料费用 ================== materialCostsService.remove(new LambdaQueryWrapper() .eq(ErpAfterSalesMaterialCosts::getAfterSalesId, afterSalesId)); - // 后新增新的 List materialBoList = bo.getMaterialCostsList(); if (CollUtil.isNotEmpty(materialBoList)) { List materialList = MapstructUtils.convert(materialBoList, ErpAfterSalesMaterialCosts.class); - // 【核心修改点 👇】遍历列表,清空 ID materialList.forEach(item -> { item.setMaterialCostsId(null); // 关键:清空ID item.setAfterSalesId(afterSalesId); @@ -275,4 +263,104 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService { } return baseMapper.deleteByIds(ids) > 0; } + + /** + * 提交项目售后信息并提交流程 + * + * @param bo + * @return + */ + @Override + @GlobalTransactional(rollbackFor = Exception.class) // 开启全局事务 + public ErpAfterSalesVo submitAndFlowStart(ErpAfterSalesBo bo) { + + ErpAfterSales add = MapstructUtils.convert(bo, ErpAfterSales.class); + validEntityBeforeSave(add); + + if (bo.getAfterSalesId() == null) { + this.insertByBo(bo); + + } else { + this.updateByBo(bo); + } + + // 准备启动流程参数 + // 后端发起需要忽略权限 + if (bo.getVariables() == null) { + bo.setVariables(new HashMap<>()); + } + bo.getVariables().put("ignore", true); + RemoteStartProcess startProcess = new RemoteStartProcess(); + startProcess.setBusinessId(bo.getAfterSalesId().toString()); + startProcess.setFlowCode(bo.getFlowCode()); + startProcess.setVariables(bo.getVariables()); + startProcess.setBizExt(bo.getBizExt()); + + // 确保 BizExt 里也有 BusinessId + if (bo.getBizExt() != null) { + bo.getBizExt().setBusinessId(startProcess.getBusinessId()); + } + + // 调用远程服务启动流程 + // startCompleteTask 表示“启动并自动完成第一个发起节点”,直接流转到下一个审批人 + boolean flagOne = remoteWorkflowService.startCompleteTask(startProcess); + + if (!flagOne) { + throw new ServiceException("流程发起异常"); + } + + return MapstructUtils.convert(add, ErpAfterSalesVo.class); + } + + /** + * 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成等) + * + * @param processEvent 参数 + */ + @EventListener(condition = "#processEvent.flowCode == 'OAAS'") + public void processHandler(ProcessEvent processEvent) { + // 多租户上下文切换(防止异步线程找不到租户) + TenantHelper.dynamic(processEvent.getTenantId(), () -> { + log.info("【售后流程监听】开始处理: key={}, status={}", processEvent.getFlowCode(), processEvent.getStatus()); + + // 根据 BusinessId 查询出当前的售后单 + Long afterSalesId = Convert.toLong(processEvent.getBusinessId()); + ErpAfterSales afterSales = baseMapper.selectById(afterSalesId); + + if (afterSales == null) { + log.error("未找到对应的售后单据,id={}", afterSalesId); + return; + } + + // 同步流程状态 (flow_status) + afterSales.setFlowStatus(processEvent.getStatus()); + + // 根据流程状态,更新业务状态 (after_sales_status) + String status = processEvent.getStatus(); + + // A. 审批中 + if (BusinessStatusEnum.WAITING.getStatus().equals(status)) { + afterSales.setAfterSalesStatus("1"); + } + // B. 流程结束/审批通过 (Finish) + else if (BusinessStatusEnum.FINISH.getStatus().equals(status)) { + afterSales.setAfterSalesStatus("2"); + } + // C. 驳回 (Back) 或 撤销 (Cancel) + else if (BusinessStatusEnum.BACK.getStatus().equals(status) + || BusinessStatusEnum.CANCEL.getStatus().equals(status)) { + afterSales.setAfterSalesStatus("0"); + } + // D. 作废 (Invalid) 或 终止 (Termination) + else if (BusinessStatusEnum.INVALID.getStatus().equals(status) + || BusinessStatusEnum.TERMINATION.getStatus().equals(status)) { + afterSales.setAfterSalesStatus("0"); + } + + // 4. 更新数据库 + baseMapper.updateById(afterSales); + }); + } + + } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpBudgetInfoServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpBudgetInfoServiceImpl.java index bae87a5a..7100a615 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpBudgetInfoServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpBudgetInfoServiceImpl.java @@ -1,6 +1,7 @@ package org.dromara.oa.erp.service.impl; import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -157,7 +158,8 @@ public class ErpBudgetInfoServiceImpl extends AbstractWorkflowService List queryBudgetCosts(BaseMapper mapper, Class entityClass, Long budgetId) { MPJLambdaWrapper wrapper = JoinWrappers.lambda(entityClass) .selectAll(entityClass) - .eq("budget_id", budgetId); // 直接使用字段名 + .eq("budget_id", budgetId) + .orderByAsc("sort_order"); // 直接使用字段名 return mapper.selectList(wrapper); } @@ -268,7 +270,6 @@ public class ErpBudgetInfoServiceImpl extends AbstractWorkflowService 0; if (add.getProjectCategory().equals(ProjectCategoryEnum.MARKET.getCode()) @@ -331,6 +332,55 @@ public class ErpBudgetInfoServiceImpl extends AbstractWorkflowService queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(ErpBudgetInfo::getProjectId, bo.getProjectId()) + .orderByDesc(ErpBudgetInfo::getBudgetVersion); + + List allBudgets = baseMapper.selectList(queryWrapper); + + if (allBudgets.isEmpty()) { + throw new RuntimeException("项目不存在"); + } + + // 2.判断此变更项目预算的状态 + ErpBudgetInfo currentEffectiveBudget = allBudgets.stream() + .filter(b -> currentBudgetVersion.equals(b.getBudgetVersion())) + .findFirst() + .orElse(null); + + if (currentEffectiveBudget == null || !currentEffectiveBudget.getBudgetStatus().equals(FlowConfigEnum.BUDGET.getCompletedBusinessStatus())) { + throw new RuntimeException("项目不存在可用的预算进行变更"); + } + + // 3. 获取最新版本号(包括所有状态的预算) + Integer latestVersion = allBudgets.stream() + .map(ErpBudgetInfo::getBudgetVersion) + .max(Integer::compareTo) + .orElse(0); + + if (latestVersion.compareTo(currentBudgetVersion) > 0) { + throw new RuntimeException("已经有正在变更的项目预算,版本号:" + latestVersion); + } + + bo.setBudgetVersion(currentBudgetVersion+1); + + return insertByBo(bo); + } + + /** * 保存前的数据校验 */ @@ -694,19 +744,19 @@ public class ErpBudgetInfoServiceImpl extends AbstractWorkflowService ids, Boolean isValid) { if (isValid) { - ids.forEach(id->{ + ids.forEach(id -> { ErpBudgetInfo erpBudgetInfo = baseMapper.selectById(id); - if(!erpBudgetInfo.getBudgetStatus().equals(OAStatusEnum.DRAFT.getStatus()) - || !erpBudgetInfo.getFlowStatus().equals(BusinessStatusEnum.DRAFT.getStatus())){ + if (!erpBudgetInfo.getBudgetStatus().equals(OAStatusEnum.DRAFT.getStatus()) + || !erpBudgetInfo.getFlowStatus().equals(BusinessStatusEnum.DRAFT.getStatus())) { throw new ServiceException("此项目预算已进入审批,不能删除!"); } LambdaUpdateWrapper luw = new LambdaUpdateWrapper<>(); // luw.set(ObjectUtil.isNull(config.getPrefix()), SysOssConfig::getPrefix, ""); - luw.set(ErpBudgetInfo::getBudgetVersion,null); - luw.set(ErpBudgetInfo::getDelFlag,"1"); + luw.set(ErpBudgetInfo::getBudgetVersion, null); + luw.set(ErpBudgetInfo::getDelFlag, "1"); luw.set(ErpBudgetInfo::getUpdateBy, LoginHelper.getUserId()); - luw.set(ErpBudgetInfo::getUpdateTime,new Date()); + luw.set(ErpBudgetInfo::getUpdateTime, new Date()); luw.eq(ErpBudgetInfo::getBudgetId, erpBudgetInfo.getBudgetId()); boolean flag = baseMapper.update(null, luw) > 0; diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectReportDetailServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectReportDetailServiceImpl.java index 978698b8..6e4e61ed 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectReportDetailServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectReportDetailServiceImpl.java @@ -1,23 +1,48 @@ package org.dromara.oa.erp.service.impl; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.map.MapUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.github.yulichang.toolkit.JoinWrappers; +import lombok.extern.slf4j.Slf4j; import com.github.yulichang.wrapper.MPJLambdaWrapper; import lombok.RequiredArgsConstructor; +import org.apache.dubbo.config.annotation.DubboReference; +import org.apache.seata.spring.annotation.GlobalTransactional; +import org.dromara.common.core.enums.BusinessStatusEnum; +import org.dromara.common.core.enums.OAStatusEnum; +import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.tenant.helper.TenantHelper; +import org.dromara.oa.erp.domain.ErpContractInfo; +import org.dromara.oa.erp.domain.ErpProjectReport; import org.dromara.oa.erp.domain.ErpProjectReportDetail; +import org.dromara.oa.erp.domain.bo.ErpContractInfoBo; +import org.dromara.oa.erp.domain.bo.ErpProjectReportBo; import org.dromara.oa.erp.domain.bo.ErpProjectReportDetailBo; +import org.dromara.oa.erp.domain.bo.ProjectReportAndDetailWrapperBo; +import org.dromara.oa.erp.domain.vo.ErpContractInfoVo; import org.dromara.oa.erp.domain.vo.ErpProjectReportDetailVo; +import org.dromara.oa.erp.domain.vo.ErpProjectReportVo; import org.dromara.oa.erp.mapper.ErpProjectReportDetailMapper; +import org.dromara.oa.erp.mapper.ErpProjectReportMapper; import org.dromara.oa.erp.service.IErpProjectReportDetailService; +import org.dromara.oa.erp.service.IErpProjectReportService; +import org.dromara.workflow.api.RemoteWorkflowService; +import org.dromara.workflow.api.domain.RemoteStartProcess; +import org.dromara.workflow.api.event.ProcessEvent; +import org.redisson.api.RedissonClient; +import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Objects; /** * 项目周报明细Service业务层处理 @@ -27,10 +52,17 @@ import java.util.Map; */ @RequiredArgsConstructor @Service +@Slf4j public class ErpProjectReportDetailServiceImpl implements IErpProjectReportDetailService { + private final IErpProjectReportService erpProjectReportService; + private final ErpProjectReportDetailMapper baseMapper; + + @DubboReference(timeout = 30000) + private RemoteWorkflowService remoteWorkflowService; + /** * 查询项目周报明细 * @@ -38,23 +70,23 @@ public class ErpProjectReportDetailServiceImpl implements IErpProjectReportDetai * @return 项目周报明细 */ @Override - public ErpProjectReportDetailVo queryById(Long reportDetailId){ + public ErpProjectReportDetailVo queryById(Long reportDetailId) { return baseMapper.selectVoById(reportDetailId); } - /** - * 分页查询项目周报明细列表 - * - * @param bo 查询条件 - * @param pageQuery 分页参数 - * @return 项目周报明细分页列表 - */ - @Override - public TableDataInfo queryPageList(ErpProjectReportDetailBo bo, PageQuery pageQuery) { - MPJLambdaWrapper lqw = buildQueryWrapper(bo); - Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - return TableDataInfo.build(result); - } + /** + * 分页查询项目周报明细列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目周报明细分页列表 + */ + @Override + public TableDataInfo queryPageList(ErpProjectReportDetailBo bo, PageQuery pageQuery) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } /** * 查询符合条件的项目周报明细列表 @@ -71,27 +103,26 @@ public class ErpProjectReportDetailServiceImpl implements IErpProjectReportDetai private MPJLambdaWrapper buildQueryWrapper(ErpProjectReportDetailBo bo) { Map params = bo.getParams(); MPJLambdaWrapper lqw = JoinWrappers.lambda(ErpProjectReportDetail.class) - .selectAll(ErpProjectReportDetail.class) - .eq(bo.getReportId() != null, ErpProjectReportDetail::getReportId, bo.getReportId()) - .eq(bo.getProjectId() != null, ErpProjectReportDetail::getProjectId, bo.getProjectId()) - .eq(bo.getFillTime() != null, ErpProjectReportDetail::getFillTime, bo.getFillTime()) - .eq(StringUtils.isNotBlank(bo.getCurrentWorkWeek()), ErpProjectReportDetail::getCurrentWorkWeek, bo.getCurrentWorkWeek()) - .eq(StringUtils.isNotBlank(bo.getMilestonePlan()), ErpProjectReportDetail::getMilestonePlan, bo.getMilestonePlan()) - .eq(StringUtils.isNotBlank(bo.getSecondaryPhase()), ErpProjectReportDetail::getSecondaryPhase, bo.getSecondaryPhase()) - .eq(StringUtils.isNotBlank(bo.getTasksCompleted()), ErpProjectReportDetail::getTasksCompleted, bo.getTasksCompleted()) - .eq(StringUtils.isNotBlank(bo.getNextPlan()), ErpProjectReportDetail::getNextPlan, bo.getNextPlan()) - .eq(StringUtils.isNotBlank(bo.getRiskResolution()), ErpProjectReportDetail::getRiskResolution, bo.getRiskResolution()) - .eq(bo.getPlannedCompletionRate() != null, ErpProjectReportDetail::getPlannedCompletionRate, bo.getPlannedCompletionRate()) - .eq(StringUtils.isNotBlank(bo.getInformationNote()), ErpProjectReportDetail::getInformationNote, bo.getInformationNote()) - .eq(StringUtils.isNotBlank(bo.getScheduleStatus()), ErpProjectReportDetail::getScheduleStatus, bo.getScheduleStatus()) - .eq(StringUtils.isNotBlank(bo.getProjectReportStatus()), ErpProjectReportDetail::getProjectReportStatus, bo.getProjectReportStatus()) - .eq(StringUtils.isNotBlank(bo.getFlowStatus()), ErpProjectReportDetail::getFlowStatus, bo.getFlowStatus()) - .eq(bo.getSortOrder() != null, ErpProjectReportDetail::getSortOrder, bo.getSortOrder()) - .eq(StringUtils.isNotBlank(bo.getProjectPhases()), ErpProjectReportDetail::getProjectPhases, bo.getProjectPhases()) - .eq(bo.getContractId() != null, ErpProjectReportDetail::getContractId, bo.getContractId()) - .eq(StringUtils.isNotBlank(bo.getOssId()), ErpProjectReportDetail::getOssId, bo.getOssId()) - .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectReportDetail::getActiveFlag, bo.getActiveFlag()) -; + .selectAll(ErpProjectReportDetail.class) + .eq(bo.getReportId() != null, ErpProjectReportDetail::getReportId, bo.getReportId()) + .eq(bo.getProjectId() != null, ErpProjectReportDetail::getProjectId, bo.getProjectId()) + .eq(bo.getFillTime() != null, ErpProjectReportDetail::getFillTime, bo.getFillTime()) + .eq(StringUtils.isNotBlank(bo.getCurrentWorkWeek()), ErpProjectReportDetail::getCurrentWorkWeek, bo.getCurrentWorkWeek()) + .eq(StringUtils.isNotBlank(bo.getMilestonePlan()), ErpProjectReportDetail::getMilestonePlan, bo.getMilestonePlan()) + .eq(StringUtils.isNotBlank(bo.getSecondaryPhase()), ErpProjectReportDetail::getSecondaryPhase, bo.getSecondaryPhase()) + .eq(StringUtils.isNotBlank(bo.getTasksCompleted()), ErpProjectReportDetail::getTasksCompleted, bo.getTasksCompleted()) + .eq(StringUtils.isNotBlank(bo.getNextPlan()), ErpProjectReportDetail::getNextPlan, bo.getNextPlan()) + .eq(StringUtils.isNotBlank(bo.getRiskResolution()), ErpProjectReportDetail::getRiskResolution, bo.getRiskResolution()) + .eq(bo.getPlannedCompletionRate() != null, ErpProjectReportDetail::getPlannedCompletionRate, bo.getPlannedCompletionRate()) + .eq(StringUtils.isNotBlank(bo.getInformationNote()), ErpProjectReportDetail::getInformationNote, bo.getInformationNote()) + .eq(StringUtils.isNotBlank(bo.getScheduleStatus()), ErpProjectReportDetail::getScheduleStatus, bo.getScheduleStatus()) + .eq(StringUtils.isNotBlank(bo.getProjectReportStatus()), ErpProjectReportDetail::getProjectReportStatus, bo.getProjectReportStatus()) + .eq(StringUtils.isNotBlank(bo.getFlowStatus()), ErpProjectReportDetail::getFlowStatus, bo.getFlowStatus()) + .eq(bo.getSortOrder() != null, ErpProjectReportDetail::getSortOrder, bo.getSortOrder()) + .eq(StringUtils.isNotBlank(bo.getProjectPhases()), ErpProjectReportDetail::getProjectPhases, bo.getProjectPhases()) + .eq(bo.getContractId() != null, ErpProjectReportDetail::getContractId, bo.getContractId()) + .eq(StringUtils.isNotBlank(bo.getOssId()), ErpProjectReportDetail::getOssId, bo.getOssId()) + .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectReportDetail::getActiveFlag, bo.getActiveFlag()); return lqw; } @@ -128,7 +159,7 @@ public class ErpProjectReportDetailServiceImpl implements IErpProjectReportDetai /** * 保存前的数据校验 */ - private void validEntityBeforeSave(ErpProjectReportDetail entity){ + private void validEntityBeforeSave(ErpProjectReportDetail entity) { //TODO 做一些数据校验,如唯一约束 } @@ -141,9 +172,83 @@ public class ErpProjectReportDetailServiceImpl implements IErpProjectReportDetai */ @Override public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if(isValid){ + if (isValid) { //TODO 做一些业务上的校验,判断是否需要校验 } return baseMapper.deleteByIds(ids) > 0; } + + /** + * 提交项目周报信息并提交流程 + * + * @param projectReport + * @param projectDetailReport + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public ErpProjectReportDetailVo projectReportSubmitAndFlowStart(ErpProjectReportBo projectReport, ErpProjectReportDetailBo projectDetailReport) { + if (StringUtils.isNotNull(projectReport.getReportId())) { + ErpProjectReportVo existingReport = erpProjectReportService.queryById(projectReport.getReportId()); + if (existingReport != null) { + erpProjectReportService.updateByBo(projectReport); + } else { + erpProjectReportService.insertByBo(projectReport); + } + } else { + erpProjectReportService.insertByBo(projectReport); + } + ErpProjectReportDetail erpProjectReportDetail = MapstructUtils.convert(projectDetailReport, ErpProjectReportDetail.class); + validEntityBeforeSave(erpProjectReportDetail); + if (StringUtils.isNull(projectDetailReport.getReportDetailId())) { + this.insertByBo(projectDetailReport); + } else { + this.updateByBo(projectDetailReport); + } + // 后端发起需要忽略权限 + projectDetailReport.getVariables().put("ignore", true); + RemoteStartProcess startProcess = new RemoteStartProcess(); + startProcess.setBusinessId(projectDetailReport.getReportDetailId().toString()); + startProcess.setFlowCode(projectDetailReport.getFlowCode()); + startProcess.setVariables(projectDetailReport.getVariables()); + startProcess.setBizExt(projectDetailReport.getBizExt()); + projectDetailReport.getBizExt().setBusinessId(startProcess.getBusinessId()); + boolean flagOne = remoteWorkflowService.startCompleteTask(startProcess); + if (!flagOne) { + throw new ServiceException("流程发起异常"); + } + return MapstructUtils.convert(erpProjectReportDetail, ErpProjectReportDetailVo.class); + } + + + /** + * 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成等) + * + * @param processEvent 参数 + */ + @EventListener(condition = "#processEvent.flowCode =='XMZB'") + public void processHandler(ProcessEvent processEvent) { + TenantHelper.dynamic(processEvent.getTenantId(), () -> { + log.info("当前任务执行了{}", processEvent.toString()); + ErpProjectReportDetail projectReportDetail = baseMapper.selectById(Convert.toLong(processEvent.getBusinessId())); + projectReportDetail.setFlowStatus(processEvent.getStatus()); + Map params = processEvent.getParams(); + if (MapUtil.isNotEmpty(params)) { + // 办理人 + String handler = Convert.toStr(params.get("handler")); + } + if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.WAITING.getStatus())) { + projectReportDetail.setProjectReportStatus(OAStatusEnum.APPROVING.getStatus()); + } else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())) { + projectReportDetail.setProjectReportStatus(OAStatusEnum.COMPLETED.getStatus()); + } else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.INVALID.getStatus()) + || Objects.equals(processEvent.getStatus(), BusinessStatusEnum.TERMINATION.getStatus())) { + projectReportDetail.setProjectReportStatus(OAStatusEnum.INVALID.getStatus()); + } else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.BACK.getStatus()) + || Objects.equals(processEvent.getStatus(), BusinessStatusEnum.CANCEL.getStatus())) { + projectReportDetail.setProjectReportStatus(OAStatusEnum.DRAFT.getStatus()); + } + baseMapper.updateById(projectReportDetail); + }); + } } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectReportServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectReportServiceImpl.java index 10e74258..9b226b54 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectReportServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectReportServiceImpl.java @@ -8,6 +8,7 @@ import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.oa.erp.domain.ErpProjectContracts; import org.dromara.oa.erp.domain.ErpProjectReport; import org.dromara.oa.erp.domain.bo.ErpProjectReportBo; import org.dromara.oa.erp.domain.vo.ErpProjectReportVo; @@ -38,23 +39,27 @@ public class ErpProjectReportServiceImpl implements IErpProjectReportService { * @return 项目周报信息 */ @Override - public ErpProjectReportVo queryById(Long reportId){ - return baseMapper.selectVoById(reportId); + public ErpProjectReportVo queryById(Long reportId) { + ErpProjectReportBo bo = new ErpProjectReportBo(); + bo.setReportId(reportId); + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + lqw.eq(reportId != null, ErpProjectReport::getReportId, bo.getReportId()); + return baseMapper.selectVoAndUserById(lqw); } - /** - * 分页查询项目周报信息列表 - * - * @param bo 查询条件 - * @param pageQuery 分页参数 - * @return 项目周报信息分页列表 - */ - @Override - public TableDataInfo queryPageList(ErpProjectReportBo bo, PageQuery pageQuery) { - MPJLambdaWrapper lqw = buildQueryWrapper(bo); - Page result = baseMapper.selectCustomErpProjectReportVoList(pageQuery.build(), lqw); - return TableDataInfo.build(result); - } + /** + * 分页查询项目周报信息列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目周报信息分页列表 + */ + @Override + public TableDataInfo queryPageList(ErpProjectReportBo bo, PageQuery pageQuery) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectCustomErpProjectReportVoList(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } /** * 查询符合条件的项目周报信息列表 @@ -65,27 +70,32 @@ public class ErpProjectReportServiceImpl implements IErpProjectReportService { @Override public List queryList(ErpProjectReportBo bo) { MPJLambdaWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); + return baseMapper.selectVoAndUserList(lqw); } private MPJLambdaWrapper buildQueryWrapper(ErpProjectReportBo bo) { Map params = bo.getParams(); MPJLambdaWrapper lqw = JoinWrappers.lambda(ErpProjectReport.class) - .selectAll(ErpProjectReport.class) - .eq(bo.getProjectId() != null, ErpProjectReport::getProjectId, bo.getProjectId()) - .like(StringUtils.isNotBlank(bo.getProjectName()), ErpProjectReport::getProjectName, bo.getProjectName()) - .eq(StringUtils.isNotBlank(bo.getMilestonePlan()), ErpProjectReport::getMilestonePlan, bo.getMilestonePlan()) - .eq(bo.getManagerId() != null, ErpProjectReport::getManagerId, bo.getManagerId()) - .eq(bo.getDeptId() != null, ErpProjectReport::getDeptId, bo.getDeptId()) - .eq(bo.getChargeId() != null, ErpProjectReport::getChargeId, bo.getChargeId()) - .eq(bo.getDeputyId() != null, ErpProjectReport::getDeputyId, bo.getDeputyId()) - .eq(StringUtils.isNotBlank(bo.getInformationNote()), ErpProjectReport::getInformationNote, bo.getInformationNote()) - .eq(bo.getSortOrder() != null, ErpProjectReport::getSortOrder, bo.getSortOrder()) - .eq(StringUtils.isNotBlank(bo.getOssId()), ErpProjectReport::getOssId, bo.getOssId()) - .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectReport::getActiveFlag, bo.getActiveFlag()) - .eq(StringUtils.isNotBlank(bo.getProjectCode()), ErpProjectReport::getProjectCode, bo.getProjectCode()) -; + .selectAll(ErpProjectReport.class) + .eq(bo.getProjectId() != null, ErpProjectReport::getProjectId, bo.getProjectId()) + .eq(StringUtils.isNotBlank(bo.getMilestonePlan()), ErpProjectReport::getMilestonePlan, bo.getMilestonePlan()) + .eq(bo.getManagerId() != null, ErpProjectReport::getManagerId, bo.getManagerId()) + .eq(bo.getDeptId() != null, ErpProjectReport::getDeptId, bo.getDeptId()) + .eq(bo.getChargeId() != null, ErpProjectReport::getChargeId, bo.getChargeId()) + .eq(bo.getDeputyId() != null, ErpProjectReport::getDeputyId, bo.getDeputyId()) + .eq(StringUtils.isNotBlank(bo.getInformationNote()), ErpProjectReport::getInformationNote, bo.getInformationNote()) + .eq(bo.getSortOrder() != null, ErpProjectReport::getSortOrder, bo.getSortOrder()) + .eq(StringUtils.isNotBlank(bo.getOssId()), ErpProjectReport::getOssId, bo.getOssId()) + .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectReport::getActiveFlag, bo.getActiveFlag()) + .eq("t.del_flag", "0") + .like(StringUtils.isNotBlank(bo.getProjectName()), ErpProjectReport::getProjectName, bo.getProjectName()) + .like(StringUtils.isNotBlank(bo.getProjectCode()), ErpProjectReport::getProjectCode, bo.getProjectCode()) + .apply(StringUtils.isNotBlank(bo.getDeptName()), "d.dept_name LIKE CONCAT('%', {0}, '%')", bo.getDeptName()) + .apply(StringUtils.isNotBlank(bo.getManagerName()), "u1.nick_name LIKE CONCAT('%', {0}, '%')", bo.getManagerName()) + .apply(StringUtils.isNotBlank(bo.getChargeName()), "u2.nick_name LIKE CONCAT('%', {0}, '%')", bo.getChargeName()) + .apply(StringUtils.isNotBlank(bo.getDeputyName()), "u3.nick_name LIKE CONCAT('%', {0}, '%')", bo.getDeputyName()); return lqw; + } /** @@ -121,7 +131,7 @@ public class ErpProjectReportServiceImpl implements IErpProjectReportService { /** * 保存前的数据校验 */ - private void validEntityBeforeSave(ErpProjectReport entity){ + private void validEntityBeforeSave(ErpProjectReport entity) { //TODO 做一些数据校验,如唯一约束 } @@ -134,7 +144,7 @@ public class ErpProjectReportServiceImpl implements IErpProjectReportService { */ @Override public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if(isValid){ + if (isValid) { //TODO 做一些业务上的校验,判断是否需要校验 } return baseMapper.deleteByIds(ids) > 0; diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectReportMapper.xml b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectReportMapper.xml index f31353d3..0ac908a6 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectReportMapper.xml +++ b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectReportMapper.xml @@ -6,38 +6,66 @@ + + + t.report_id, + t.tenant_id, + t.project_id, + t.project_name, + t.milestone_plan, + t.manager_id, + t.dept_id, + t.charge_id, + t.deputy_id, + t.information_note, + t.sort_order, + t.oss_id, + t.remark, + t.active_flag, + t.del_flag, + t.create_dept, + t.create_by, + t.create_time, + t.update_by, + t.update_time, + t.project_code, + d.dept_name AS deptName, + u1.nick_name AS managerName, + u2.nick_name AS chargeName, + u3.nick_name AS deputyName + + + + + FROM erp_project_report t + LEFT JOIN sys_dept d ON d.dept_id = t.dept_id + LEFT JOIN sys_user u1 ON u1.user_id = t.manager_id + LEFT JOIN sys_user u2 ON u2.user_id = t.charge_id + LEFT JOIN sys_user u3 ON u3.user_id = t.deputy_id + + + + + + + + + diff --git a/sessionStore/8091/root.data b/sessionStore/8091/root.data new file mode 100644 index 00000000..e69de29b