diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/dto/QuoteTemplateDto.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/dto/QuoteTemplateDto.java new file mode 100644 index 00000000..e2586e18 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/dto/QuoteTemplateDto.java @@ -0,0 +1,93 @@ +package org.dromara.oa.crm.domain.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 报价单模板DTO + * 用于Excel模板导出的字段映射 + * + * @author Yinq + * @date 2025-10-30 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class QuoteTemplateDto { + + /** + * 客户方联系人 + */ + private String customerContactName; + + /** + * 标题(报价单名称) + */ + private String title; + + /** + * 报价日期 + */ + private String quoteDate; + + /** + * 含税信息 + */ + private String taxIncludedInfo; + + /** + * 付款方式 + */ + private String paymentMethod; + + /** + * 交货期 + */ + private String deliveryPeriod; + + /** + * 交货方式 + */ + private String deliveryMethod; + + /** + * 报价有效期 + */ + private String validDays; + + /** + * 未税总价 + */ + private String totalBeforeTax; + + /** + * 税额 + */ + private String totalTax; + + /** + * 含税总价 + */ + private String totalIncludingTax; + + /** + * 总价大写 + */ + private String totalInChinese; + + /** + * 供货方联系人 + */ + private String supplierContactName; + + /** + * 供货方联系电话 + */ + private String supplierContactPhone; + + /** + * 供货方电子邮箱 + */ + private String supplierContactEmail; +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/dto/QuoteTemplateItemDto.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/dto/QuoteTemplateItemDto.java new file mode 100644 index 00000000..57f9c3d1 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/dto/QuoteTemplateItemDto.java @@ -0,0 +1,51 @@ +package org.dromara.oa.crm.domain.dto; + +import cn.idev.excel.annotation.ExcelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 报价单模板明细项 DTO + * 用于 EasyExcel 模板填充 + * + * @author Yinq + * @date 2025-10-29 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class QuoteTemplateItemDto implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** 序号 */ + private Long seq; + + /** 产品名称 */ + private String productName; + + /** 型号/说明 */ + private String modelDesc; + + /** 数量 */ + private BigDecimal quantity; + + /** 单位 */ + private String unit; + + /** 单价(含税) */ + private BigDecimal price; + + /** 小计(含税) */ + private BigDecimal subtotal; + + /** 备注 */ + private String remark; + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/dto/QuoteTemplateMaterialDto.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/dto/QuoteTemplateMaterialDto.java new file mode 100644 index 00000000..cbddbdb1 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/dto/QuoteTemplateMaterialDto.java @@ -0,0 +1,58 @@ +package org.dromara.oa.crm.domain.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 报价单模板物料明细DTO + * 用于Excel模板导出的物料明细字段映射 + * + * @author Yinq + * @date 2025-10-30 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class QuoteTemplateMaterialDto { + + /** + * 序号 + */ + private String seq; + + /** + * 产品/服务名称 + */ + private String productName; + + /** + * 型号/说明 + */ + private String modelDesc; + + /** + * 数量 + */ + private String quantity; + + /** + * 单位 + */ + private String unit; + + /** + * 单价 + */ + private String price; + + /** + * 小计(含税) + */ + private String subtotal; + + /** + * 备注 + */ + private String remark; +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectChangeBudgetController.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectChangeBudgetController.java new file mode 100644 index 00000000..16a178c0 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectChangeBudgetController.java @@ -0,0 +1,116 @@ +package org.dromara.oa.erp.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.oa.erp.domain.vo.ErpProjectChangeBudgetVo; +import org.dromara.oa.erp.domain.bo.ErpProjectChangeBudgetBo; +import org.dromara.oa.erp.service.IErpProjectChangeBudgetService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 项目预算变更明细 + * 前端访问路由地址为:/oa/erp/erpProjectChangeBudget + * + * @author Yinq + * @date 2025-11-10 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/erpProjectChangeBudget") +public class ErpProjectChangeBudgetController extends BaseController { + + private final IErpProjectChangeBudgetService erpProjectChangeBudgetService; + + /** + * 查询项目预算变更明细列表 + */ + @SaCheckPermission("oa/erp:erpProjectChangeBudget:list") + @GetMapping("/list") + public TableDataInfo list(ErpProjectChangeBudgetBo bo, PageQuery pageQuery) { + return erpProjectChangeBudgetService.queryPageList(bo, pageQuery); + } + + /** + * 导出项目预算变更明细列表 + */ + @SaCheckPermission("oa/erp:erpProjectChangeBudget:export") + @Log(title = "项目预算变更明细", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(ErpProjectChangeBudgetBo bo, HttpServletResponse response) { + List list = erpProjectChangeBudgetService.queryList(bo); + ExcelUtil.exportExcel(list, "项目预算变更明细", ErpProjectChangeBudgetVo.class, response); + } + + /** + * 获取项目预算变更明细详细信息 + * + * @param changeBudgetId 主键 + */ + @SaCheckPermission("oa/erp:erpProjectChangeBudget:query") + @GetMapping("/{changeBudgetId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable("changeBudgetId") Long changeBudgetId) { + return R.ok(erpProjectChangeBudgetService.queryById(changeBudgetId)); + } + + /** + * 新增项目预算变更明细 + */ + @SaCheckPermission("oa/erp:erpProjectChangeBudget:add") + @Log(title = "项目预算变更明细", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody ErpProjectChangeBudgetBo bo) { + return toAjax(erpProjectChangeBudgetService.insertByBo(bo)); + } + + /** + * 修改项目预算变更明细 + */ + @SaCheckPermission("oa/erp:erpProjectChangeBudget:edit") + @Log(title = "项目预算变更明细", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody ErpProjectChangeBudgetBo bo) { + return toAjax(erpProjectChangeBudgetService.updateByBo(bo)); + } + + /** + * 删除项目预算变更明细 + * + * @param changeBudgetIds 主键串 + */ + @SaCheckPermission("oa/erp:erpProjectChangeBudget:remove") + @Log(title = "项目预算变更明细", businessType = BusinessType.DELETE) + @DeleteMapping("/{changeBudgetIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable("changeBudgetIds") Long[] changeBudgetIds) { + return toAjax(erpProjectChangeBudgetService.deleteWithValidByIds(List.of(changeBudgetIds), true)); + } + + /** + * 下拉框查询项目预算变更明细列表 + */ + @GetMapping("/getErpProjectChangeBudgetList") + public R> getErpProjectChangeBudgetList(ErpProjectChangeBudgetBo bo) { + List list = erpProjectChangeBudgetService.queryList(bo); + return R.ok(list); + } + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectChangeController.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectChangeController.java new file mode 100644 index 00000000..60a74ee8 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectChangeController.java @@ -0,0 +1,139 @@ +package org.dromara.oa.erp.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.oa.erp.domain.vo.ErpProjectChangeVo; +import org.dromara.oa.erp.domain.bo.ErpProjectChangeBo; +import org.dromara.oa.erp.service.IErpProjectChangeService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 项目变更申请 + * 前端访问路由地址为:/oa/erp/erpProjectChange + * + * @author Yinq + * @date 2025-11-10 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/erp/erpProjectChange") +public class ErpProjectChangeController extends BaseController { + + private final IErpProjectChangeService erpProjectChangeService; + + /** + * 查询项目变更申请列表 + */ + @SaCheckPermission("oa/erp:erpProjectChange:list") + @GetMapping("/list") + public TableDataInfo list(ErpProjectChangeBo bo, PageQuery pageQuery) { + return erpProjectChangeService.queryPageList(bo, pageQuery); + } + + /** + * 导出项目变更申请列表 + */ + @SaCheckPermission("oa/erp:erpProjectChange:export") + @Log(title = "项目变更申请", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(ErpProjectChangeBo bo, HttpServletResponse response) { + List list = erpProjectChangeService.queryList(bo); + ExcelUtil.exportExcel(list, "项目变更申请", ErpProjectChangeVo.class, response); + } + + /** + * 获取项目变更申请详细信息 + * + * @param projectChangeId 主键 + */ + @SaCheckPermission("oa/erp:erpProjectChange:query") + @GetMapping("/{projectChangeId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable("projectChangeId") Long projectChangeId) { + return R.ok(erpProjectChangeService.queryById(projectChangeId)); + } + + /** + * 新增项目变更申请 + */ + @SaCheckPermission("oa/erp:erpProjectChange:add") + @Log(title = "项目变更申请", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody ErpProjectChangeBo bo) { + return toAjax(erpProjectChangeService.insertByBo(bo)); + } + + /** + * 修改项目变更申请 + */ + @SaCheckPermission("oa/erp:erpProjectChange:edit") + @Log(title = "项目变更申请", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody ErpProjectChangeBo bo) { + return toAjax(erpProjectChangeService.updateByBo(bo)); + } + + /** + * 删除项目变更申请 + * + * @param projectChangeIds 主键串 + */ + @SaCheckPermission("oa/erp:erpProjectChange:remove") + @Log(title = "项目变更申请", businessType = BusinessType.DELETE) + @DeleteMapping("/{projectChangeIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable("projectChangeIds") Long[] projectChangeIds) { + return toAjax(erpProjectChangeService.deleteWithValidByIds(List.of(projectChangeIds), true)); + } + + /** + * 下拉框查询项目变更申请列表 + */ + @GetMapping("/getErpProjectChangeList") + public R> getErpProjectChangeList(ErpProjectChangeBo bo) { + List list = erpProjectChangeService.queryList(bo); + return R.ok(list); + } + + /** + * 根据项目ID准备项目变更信息(带出项目信息和项目计划阶段) + * + * @param projectId 项目ID + */ + @SaCheckPermission("oa/erp:erpProjectChange:query") + @GetMapping("/prepareWithInfo/{projectId}") + public R prepareWithInfo(@NotNull(message = "项目ID不能为空") + @PathVariable("projectId") Long projectId) { + return R.ok(erpProjectChangeService.prepareByProjectWithInfo(projectId)); + } + + /** + * 提交项目变更并发起审批流 + */ + @SaCheckPermission("oa/erp:erpProjectChange:add") + @Log(title = "项目变更申请", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/submitAndFlowStart") + public R submitAndFlowStart(@Validated(AddGroup.class) @RequestBody ErpProjectChangeBo bo) { + return R.ok(erpProjectChangeService.projectChangeSubmitAndFlowStart(bo)); + } + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectChangeProgressController.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectChangeProgressController.java new file mode 100644 index 00000000..ca3fe7b9 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectChangeProgressController.java @@ -0,0 +1,116 @@ +package org.dromara.oa.erp.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.oa.erp.domain.vo.ErpProjectChangeProgressVo; +import org.dromara.oa.erp.domain.bo.ErpProjectChangeProgressBo; +import org.dromara.oa.erp.service.IErpProjectChangeProgressService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 项目进度变更明细 + * 前端访问路由地址为:/oa/erp/erpProjectChangeProgress + * + * @author Yinq + * @date 2025-11-10 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/erpProjectChangeProgress") +public class ErpProjectChangeProgressController extends BaseController { + + private final IErpProjectChangeProgressService erpProjectChangeProgressService; + + /** + * 查询项目进度变更明细列表 + */ + @SaCheckPermission("oa/erp:erpProjectChangeProgress:list") + @GetMapping("/list") + public TableDataInfo list(ErpProjectChangeProgressBo bo, PageQuery pageQuery) { + return erpProjectChangeProgressService.queryPageList(bo, pageQuery); + } + + /** + * 导出项目进度变更明细列表 + */ + @SaCheckPermission("oa/erp:erpProjectChangeProgress:export") + @Log(title = "项目进度变更明细", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(ErpProjectChangeProgressBo bo, HttpServletResponse response) { + List list = erpProjectChangeProgressService.queryList(bo); + ExcelUtil.exportExcel(list, "项目进度变更明细", ErpProjectChangeProgressVo.class, response); + } + + /** + * 获取项目进度变更明细详细信息 + * + * @param changeProgressId 主键 + */ + @SaCheckPermission("oa/erp:erpProjectChangeProgress:query") + @GetMapping("/{changeProgressId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable("changeProgressId") Long changeProgressId) { + return R.ok(erpProjectChangeProgressService.queryById(changeProgressId)); + } + + /** + * 新增项目进度变更明细 + */ + @SaCheckPermission("oa/erp:erpProjectChangeProgress:add") + @Log(title = "项目进度变更明细", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody ErpProjectChangeProgressBo bo) { + return toAjax(erpProjectChangeProgressService.insertByBo(bo)); + } + + /** + * 修改项目进度变更明细 + */ + @SaCheckPermission("oa/erp:erpProjectChangeProgress:edit") + @Log(title = "项目进度变更明细", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody ErpProjectChangeProgressBo bo) { + return toAjax(erpProjectChangeProgressService.updateByBo(bo)); + } + + /** + * 删除项目进度变更明细 + * + * @param changeProgressIds 主键串 + */ + @SaCheckPermission("oa/erp:erpProjectChangeProgress:remove") + @Log(title = "项目进度变更明细", businessType = BusinessType.DELETE) + @DeleteMapping("/{changeProgressIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable("changeProgressIds") Long[] changeProgressIds) { + return toAjax(erpProjectChangeProgressService.deleteWithValidByIds(List.of(changeProgressIds), true)); + } + + /** + * 下拉框查询项目进度变更明细列表 + */ + @GetMapping("/getErpProjectChangeProgressList") + public R> getErpProjectChangeProgressList(ErpProjectChangeProgressBo bo) { + List list = erpProjectChangeProgressService.queryList(bo); + return R.ok(list); + } + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectChange.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectChange.java new file mode 100644 index 00000000..7f2d833f --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectChange.java @@ -0,0 +1,149 @@ +package org.dromara.oa.erp.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serial; + +/** + * 项目变更申请对象 erp_project_change + * + * @author Yinq + * @date 2025-11-10 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("erp_project_change") +public class ErpProjectChange extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 项目变更ID + */ + @TableId(value = "project_change_id", type = IdType.ASSIGN_ID) + private Long projectChangeId; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 项目编号 + */ + private String projectCode; + + /** + * 项目名称 + */ + private String projectName; + + /** + * 项目类别(1销售(实施、物流) 2销售(备件) 3研发 4预投) + */ + private String projectCategory; + + /** + * 变更类型(多选)(1预算变更 2计划变更 3范围变更 4需求变更 5合同变更) + */ + private String changeType; + + /** + * 变更次数 + */ + private Integer changeNumber; + + /** + * 项目经理ID + */ + private Long projectManagerId; + + /** + * 项目经理姓名 + */ + private String projectManagerName; + + /** + * 部门负责人ID + */ + private Long deptHeadId; + + /** + * 部门负责人姓名 + */ + private String deptHeadName; + + /** + * 分管副总ID + */ + private Long responsibleVpId; + + /** + * 分管副总姓名 + */ + private String responsibleVpName; + + /** + * 申请变更时间 + */ + private Date applyChangeDate; + + /** + * 项目合同额 + */ + private BigDecimal contractAmount; + + /** + * 项目合同净额 + */ + private BigDecimal contractNetAmount; + + /** + * 项目当前情况 + */ + private String currentStatus; + + /** + * 变更原因 + */ + private String changeReason; + + /** + * 后续工作 + */ + private String followUpWork; + + /** + * 项目变更状态(1暂存 2审批中 3可用) + */ + private String projectChangeStatus; + + /** + * 流程状态 + */ + private String flowStatus; + + /** + * 备注 + */ + private String remark; + + /** + * 激活标识(1是 0否) + */ + private String activeFlag; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @TableLogic + private String delFlag; + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectChangeBudget.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectChangeBudget.java new file mode 100644 index 00000000..24b9c930 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectChangeBudget.java @@ -0,0 +1,85 @@ +package org.dromara.oa.erp.domain; + +import org.dromara.common.mybatis.core.domain.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.tenant.core.TenantEntity; + +import java.math.BigDecimal; + +import java.io.Serial; + +/** + * 项目预算变更明细对象 erp_project_change_budget + * + * @author Yinq + * @date 2025-11-10 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("erp_project_change_budget") +public class ErpProjectChangeBudget extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 预算变更ID + */ + @TableId(value = "change_budget_id", type = IdType.AUTO) + private Long changeBudgetId; + + /** + * 变更申请ID + */ + private Long projectChangeId; + + /** + * 预算详情ID + */ + private Long budgetDetailId; + + /** + * 科目名称(材料费、人工费、安装费、差旅费、其他费用) + */ + private String subjectName; + + /** + * 变更前预算 + */ + private BigDecimal budgetBefore; + + /** + * 变更后预算 + */ + private BigDecimal budgetAfter; + + /** + * 已使用金额 + */ + private BigDecimal amountUsed; + + /** + * 费用调整原因 + */ + private String adjustmentReason; + + /** + * 排序顺序 + */ + private Long sortOrder; + + /** + * 备注 + */ + private String remark; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @TableLogic + private String delFlag; + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectChangeProgress.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectChangeProgress.java new file mode 100644 index 00000000..42e6472f --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectChangeProgress.java @@ -0,0 +1,97 @@ +package org.dromara.oa.erp.domain; + +import org.dromara.common.mybatis.core.domain.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.dromara.common.tenant.core.TenantEntity; + +import java.io.Serial; + +/** + * 项目进度变更明细对象 erp_project_change_progress + * + * @author Yinq + * @date 2025-11-10 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("erp_project_change_progress") +public class ErpProjectChangeProgress extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 进度变更ID + */ + @TableId(value = "change_progress_id", type = IdType.AUTO) + private Long changeProgressId; + + /** + * 变更申请ID + */ + private Long projectChangeId; + + /** + * 计划阶段ID + */ + private Long planStageId; + + /** + * 项目阶段(字典project_phases) + */ + @TableField(exist = false) + private String projectPhases; + + /** + * 项目里程碑 + */ + private String milestoneName; + + /** + * 原计划时间起 + */ + private Date originalStart; + + /** + * 原计划时间止 + */ + private Date originalEnd; + + /** + * 变更后时间起 + */ + private Date changedStart; + + /** + * 变更后时间止 + */ + private Date changedEnd; + + /** + * 里程碑完成程度(百分比) + */ + private BigDecimal completionDegree; + + /** + * 排序顺序 + */ + private Long sortOrder; + + /** + * 备注 + */ + private String remark; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @TableLogic + private String delFlag; + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectChangeBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectChangeBo.java new file mode 100644 index 00000000..209fb1d1 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectChangeBo.java @@ -0,0 +1,195 @@ +package org.dromara.oa.erp.domain.bo; + +import cn.hutool.core.util.ObjectUtil; +import org.dromara.oa.erp.domain.ErpProjectChange; +import org.dromara.oa.erp.domain.ErpProjectChangeBudget; +import org.dromara.oa.erp.domain.ErpProjectChangeProgress; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; +import java.math.BigDecimal; +import java.util.*; + +import com.fasterxml.jackson.annotation.JsonFormat; +import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt; + +/** + * 项目变更申请业务对象 erp_project_change + * + * @author Yinq + * @date 2025-11-10 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = ErpProjectChange.class, reverseConvertGenerate = false) +public class ErpProjectChangeBo extends BaseEntity { + + /** + * 项目变更ID + */ + @NotNull(message = "项目变更ID不能为空", groups = { EditGroup.class }) + private Long projectChangeId; + + /** + * 项目ID + */ + @NotNull(message = "项目ID不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long projectId; + + /** + * 项目编号 + */ + private String projectCode; + + /** + * 项目名称 + */ + private String projectName; + + /** + * 项目类别(1销售(实施、物流) 2销售(备件) 3研发 4预投) + */ + private String projectCategory; + + /** + * 变更类型(多选)(1预算变更 2计划变更 3范围变更 4需求变更 5合同变更) + */ + private String changeType; + + /** + * 变更次数 + */ + private Integer changeNumber; + + /** + * 项目经理ID + */ + private Long projectManagerId; + + /** + * 项目经理姓名 + */ + private String projectManagerName; + + /** + * 部门负责人ID + */ + private Long deptHeadId; + + /** + * 部门负责人姓名 + */ + private String deptHeadName; + + /** + * 分管副总ID + */ + private Long responsibleVpId; + + /** + * 分管副总姓名 + */ + private String responsibleVpName; + + /** + * 申请变更时间 + */ + @NotNull(message = "申请变更时间不能为空", groups = { AddGroup.class, EditGroup.class }) + private Date applyChangeDate; + + /** + * 项目合同额 + */ + private BigDecimal contractAmount; + + /** + * 项目合同净额 + */ + private BigDecimal contractNetAmount; + + /** + * 项目当前情况 + */ + private String currentStatus; + + /** + * 变更原因 + */ + private String changeReason; + + /** + * 后续工作 + */ + private String followUpWork; + + /** + * 项目变更状态(1暂存 2审批中 3可用) + */ + private String projectChangeStatus; + + /** + * 流程状态 + */ + private String flowStatus; + + /** + * 备注 + */ + private String remark; + + /** + * 激活标识(1是 0否) + */ + private String activeFlag; + + /** + * 预算变更明细列表 + */ + private List budgetList; + + /** + * 进度变更明细列表 + */ + private List progressList; + + /** + * 流程编码 + */ + private String flowCode; + + /** + * 流程处理人 + */ + private String handler; + + /** + * 流程变量,前端会提交一个元素{'entity': {业务详情数据对象}} + */ + private Map variables; + + /** + * 流程业务扩展信息 + */ + private RemoteFlowInstanceBizExt bizExt; + + 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/ErpProjectChangeBudgetBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectChangeBudgetBo.java new file mode 100644 index 00000000..bbf6b8a6 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectChangeBudgetBo.java @@ -0,0 +1,78 @@ +package org.dromara.oa.erp.domain.bo; + +import org.dromara.oa.erp.domain.ErpProjectChangeBudget; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; +import java.math.BigDecimal; + +/** + * 项目预算变更明细业务对象 erp_project_change_budget + * + * @author Yinq + * @date 2025-11-10 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = ErpProjectChangeBudget.class, reverseConvertGenerate = false) +public class ErpProjectChangeBudgetBo extends BaseEntity { + + /** + * 预算变更ID + */ + @NotNull(message = "预算变更ID不能为空", groups = { EditGroup.class }) + private Long changeBudgetId; + + /** + * 变更申请ID + */ + @NotNull(message = "变更申请ID不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long projectChangeId; + + /** + * 预算详情ID + */ + private Long budgetDetailId; + + /** + * 科目名称(材料费、人工费、安装费、差旅费、其他费用) + */ + @NotBlank(message = "科目名称(材料费、人工费、安装费、差旅费、其他费用)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String subjectName; + + /** + * 变更前预算 + */ + private BigDecimal budgetBefore; + + /** + * 变更后预算 + */ + private BigDecimal budgetAfter; + + /** + * 已使用金额 + */ + private BigDecimal amountUsed; + + /** + * 费用调整原因 + */ + private String adjustmentReason; + + /** + * 排序顺序 + */ + private Long sortOrder; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectChangeProgressBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectChangeProgressBo.java new file mode 100644 index 00000000..64641fda --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectChangeProgressBo.java @@ -0,0 +1,86 @@ +package org.dromara.oa.erp.domain.bo; + +import org.dromara.oa.erp.domain.ErpProjectChangeProgress; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 项目进度变更明细业务对象 erp_project_change_progress + * + * @author Yinq + * @date 2025-11-10 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = ErpProjectChangeProgress.class, reverseConvertGenerate = false) +public class ErpProjectChangeProgressBo extends BaseEntity { + + /** + * 进度变更ID + */ + @NotNull(message = "进度变更ID不能为空", groups = { EditGroup.class }) + private Long changeProgressId; + + /** + * 变更申请ID + */ + @NotNull(message = "变更申请ID不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long projectChangeId; + + /** + * 计划阶段ID + */ + @NotNull(message = "计划阶段ID不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long planStageId; + + /** + * 项目里程碑 + */ + @NotBlank(message = "项目里程碑不能为空", groups = { AddGroup.class, EditGroup.class }) + private String milestoneName; + + /** + * 原计划时间起 + */ + private Date originalStart; + + /** + * 原计划时间止 + */ + private Date originalEnd; + + /** + * 变更后时间起 + */ + private Date changedStart; + + /** + * 变更后时间止 + */ + private Date changedEnd; + + /** + * 里程碑完成程度(百分比) + */ + private BigDecimal completionDegree; + + /** + * 排序顺序 + */ + private Long sortOrder; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectChangeBudgetVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectChangeBudgetVo.java new file mode 100644 index 00000000..c3a87632 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectChangeBudgetVo.java @@ -0,0 +1,94 @@ +package org.dromara.oa.erp.domain.vo; + +import java.math.BigDecimal; +import org.dromara.oa.erp.domain.ErpProjectChangeBudget; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 项目预算变更明细视图对象 erp_project_change_budget + * + * @author Yinq + * @date 2025-11-10 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = ErpProjectChangeBudget.class) +public class ErpProjectChangeBudgetVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 预算变更ID + */ + @ExcelProperty(value = "预算变更ID") + private Long changeBudgetId; + + /** + * 变更申请ID + */ + @ExcelProperty(value = "变更申请ID") + private Long projectChangeId; + + /** + * 预算详情ID + */ + @ExcelProperty(value = "预算详情ID") + private Long budgetDetailId; + + /** + * 科目名称(材料费、人工费、安装费、差旅费、其他费用) + */ + @ExcelProperty(value = "科目名称", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "材=料费、人工费、安装费、差旅费、其他费用") + private String subjectName; + + /** + * 变更前预算 + */ + @ExcelProperty(value = "变更前预算") + private BigDecimal budgetBefore; + + /** + * 变更后预算 + */ + @ExcelProperty(value = "变更后预算") + private BigDecimal budgetAfter; + + /** + * 已使用金额 + */ + @ExcelProperty(value = "已使用金额") + private BigDecimal amountUsed; + + /** + * 费用调整原因 + */ + @ExcelProperty(value = "费用调整原因") + private String adjustmentReason; + + /** + * 排序顺序 + */ + @ExcelProperty(value = "排序顺序") + private Long sortOrder; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectChangeProgressVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectChangeProgressVo.java new file mode 100644 index 00000000..e65708c7 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectChangeProgressVo.java @@ -0,0 +1,109 @@ +package org.dromara.oa.erp.domain.vo; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.dromara.oa.erp.domain.ErpProjectChangeProgress; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 项目进度变更明细视图对象 erp_project_change_progress + * + * @author Yinq + * @date 2025-11-10 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = ErpProjectChangeProgress.class) +public class ErpProjectChangeProgressVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 进度变更ID + */ + @ExcelProperty(value = "进度变更ID") + private Long changeProgressId; + + /** + * 变更申请ID + */ + @ExcelProperty(value = "变更申请ID") + private Long projectChangeId; + + /** + * 计划阶段ID + */ + @ExcelProperty(value = "计划阶段ID") + private Long planStageId; + + /** + * 项目阶段(字典project_phases) + */ + @ExcelProperty(value = "项目阶段", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "project_phases") + private String projectPhases; + + /** + * 项目里程碑 + */ + @ExcelProperty(value = "项目里程碑") + private String milestoneName; + + /** + * 原计划时间起 + */ + @ExcelProperty(value = "原计划时间起") + private Date originalStart; + + /** + * 原计划时间止 + */ + @ExcelProperty(value = "原计划时间止") + private Date originalEnd; + + /** + * 变更后时间起 + */ + @ExcelProperty(value = "变更后时间起") + private Date changedStart; + + /** + * 变更后时间止 + */ + @ExcelProperty(value = "变更后时间止") + private Date changedEnd; + + /** + * 里程碑完成程度(百分比) + */ + @ExcelProperty(value = "里程碑完成程度", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "百=分比") + private BigDecimal completionDegree; + + /** + * 排序顺序 + */ + @ExcelProperty(value = "排序顺序") + private Long sortOrder; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectChangeVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectChangeVo.java new file mode 100644 index 00000000..421eb6a3 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectChangeVo.java @@ -0,0 +1,204 @@ +package org.dromara.oa.erp.domain.vo; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.dromara.oa.erp.domain.ErpProjectChange; +import org.dromara.oa.erp.domain.ErpProjectChangeBudget; +import org.dromara.oa.erp.domain.ErpProjectChangeProgress; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import com.baomidou.mybatisplus.annotation.TableField; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 项目变更申请视图对象 erp_project_change + * + * @author Yinq + * @date 2025-11-10 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = ErpProjectChange.class) +public class ErpProjectChangeVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 项目变更ID + */ + @ExcelProperty(value = "项目变更ID") + private Long projectChangeId; + + /** + * 项目ID + */ + @ExcelProperty(value = "项目ID") + private Long projectId; + + /** + * 项目编号 + */ + @ExcelProperty(value = "项目编号") + private String projectCode; + + /** + * 项目名称 + */ + @ExcelProperty(value = "项目名称") + private String projectName; + + /** + * 项目类别(1销售(实施、物流) 2销售(备件) 3研发 4预投) + */ + @ExcelProperty(value = "项目类别", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "project_category") + private String projectCategory; + + /** + * 变更类型(多选)(1预算变更 2计划变更 3范围变更 4需求变更 5合同变更) + */ + @ExcelProperty(value = "变更类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "change_type") + private String changeType; + + /** + * 变更次数 + */ + @ExcelProperty(value = "变更次数") + private Integer changeNumber; + + /** + * 项目经理ID + */ + @ExcelProperty(value = "项目经理ID") + private Long projectManagerId; + + /** + * 项目经理姓名 + */ + @ExcelProperty(value = "项目经理姓名") + private String projectManagerName; + + /** + * 部门负责人ID + */ + @ExcelProperty(value = "部门负责人ID") + private Long deptHeadId; + + /** + * 部门负责人姓名 + */ + @ExcelProperty(value = "部门负责人姓名") + private String deptHeadName; + + /** + * 分管副总ID + */ + @ExcelProperty(value = "分管副总ID") + private Long responsibleVpId; + + /** + * 分管副总姓名 + */ + @ExcelProperty(value = "分管副总姓名") + private String responsibleVpName; + + /** + * 申请变更时间 + */ + @ExcelProperty(value = "申请变更时间") + private Date applyChangeDate; + + /** + * 项目合同额 + */ + @ExcelProperty(value = "项目合同额") + private BigDecimal contractAmount; + + /** + * 项目合同净额 + */ + @ExcelProperty(value = "项目合同净额") + private BigDecimal contractNetAmount; + + /** + * 项目当前情况 + */ + @ExcelProperty(value = "项目当前情况") + private String currentStatus; + + /** + * 变更原因 + */ + @ExcelProperty(value = "变更原因") + private String changeReason; + + /** + * 后续工作 + */ + @ExcelProperty(value = "后续工作") + private String followUpWork; + + /** + * 项目变更状态(1暂存 2审批中 3可用) + */ + @ExcelProperty(value = "项目变更状态(1暂存 2审批中 3可用)", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "project_change_status") + private String projectChangeStatus; + + /** + * 流程状态 + */ + @ExcelProperty(value = "流程状态") + private String flowStatus; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 激活标识(1是 0否) + */ + @ExcelProperty(value = "激活标识", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "active_flag") + private String activeFlag; + + /** + * 创建人 + */ + @ExcelProperty(value = "创建人") + private Long createBy; + + /** + * 创建时间 + */ + @ExcelProperty(value = "创建时间") + private Date createTime; + + /** + * 预算变更明细列表 + */ + @TableField(exist = false) + private List budgetList; + + /** + * 进度变更明细列表 + */ + @TableField(exist = false) + private List progressList; + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectChangeBudgetMapper.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectChangeBudgetMapper.java new file mode 100644 index 00000000..597162fb --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectChangeBudgetMapper.java @@ -0,0 +1,113 @@ +package org.dromara.oa.erp.mapper; + +import java.util.List; +import java.util.Collection; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; +import org.dromara.oa.erp.domain.ErpProjectChangeBudget; +import org.dromara.oa.erp.domain.vo.ErpProjectChangeBudgetVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 项目预算变更明细Mapper接口 + * + * @author Yinq + * @date 2025-11-10 + */ +public interface ErpProjectChangeBudgetMapper extends BaseMapperPlus { + + /** + * 查询项目预算变更明细列表 + * + * @param page 分页 + * @param queryWrapper 条件 + * @return 项目预算变更明细集合 + */ + public Page selectCustomErpProjectChangeBudgetVoList(@Param("page") Page page, @Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + /** + * 查询项目预算变更明细列表 + * + * @param queryWrapper 条件 + * @return 项目预算变更明细集合 + */ + public List selectCustomErpProjectChangeBudgetVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + /** + * 根据ID查询项目预算变更明细详情 + * + * @param changeBudgetId 主键ID + * @return 项目预算变更明细对象 + */ + ErpProjectChangeBudgetVo selectCustomErpProjectChangeBudgetVoById(@Param("changeBudgetId") Long changeBudgetId); + + /** + * 根据ID列表批量查询项目预算变更明细 + * + * @param ids ID集合 + * @return 项目预算变更明细集合 + */ + List selectCustomErpProjectChangeBudgetVoByIds(@Param("ids") Collection ids); + + /** + * 统计项目预算变更明细记录数 + * + * @param queryWrapper 查询条件 + * @return 记录总数 + */ + Long countCustomErpProjectChangeBudget(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 分页查询项目预算变更明细(自定义条件) + * + * @param page 分页对象 + * @param queryWrapper 查询条件 + * @return 分页结果 + */ + Page selectCustomErpProjectChangeBudgetVoPage(@Param("page") Page page, @Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 批量插入项目预算变更明细 + * + * @param list 项目预算变更明细对象集合 + * @return 影响行数 + */ + int batchInsertErpProjectChangeBudget(@Param("list") List list); + + /** + * 批量更新项目预算变更明细 + * + * @param list 项目预算变更明细对象集合 + * @return 影响行数 + */ + int batchUpdateErpProjectChangeBudget(@Param("list") List list); + + /** + * 根据自定义条件删除项目预算变更明细 + * + * @param queryWrapper 删除条件 + * @return 影响行数 + */ + int deleteCustomErpProjectChangeBudget(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 根据ID列表批量删除项目预算变更明细 + * + * @param ids ID集合 + * @return 影响行数 + */ + int deleteCustomErpProjectChangeBudgetByIds(@Param("ids") Collection ids); + + /** + * 检查项目预算变更明细是否存在 + * + * @param queryWrapper 查询条件 + * @return 是否存在 + */ + Boolean existsErpProjectChangeBudget(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectChangeMapper.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectChangeMapper.java new file mode 100644 index 00000000..099c5de0 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectChangeMapper.java @@ -0,0 +1,131 @@ +package org.dromara.oa.erp.mapper; + +import java.util.List; +import java.util.Collection; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; +import org.dromara.oa.erp.domain.ErpProjectChange; +import org.dromara.oa.erp.domain.vo.ErpProjectChangeVo; +import org.dromara.common.mybatis.annotation.DataColumn; +import org.dromara.common.mybatis.annotation.DataPermission; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 项目变更申请Mapper接口 + * + * @author Yinq + * @date 2025-11-10 + */ +public interface ErpProjectChangeMapper extends BaseMapperPlus { + + /** + * 查询项目变更申请列表 + * + * @param page 分页 + * @param queryWrapper 条件 + * @return 项目变更申请集合 + */ + @DataPermission({ + @DataColumn(key = "deptName", value = "t.create_dept"), + @DataColumn(key = "userName", value = "t.create_by") + }) + public Page selectCustomErpProjectChangeVoList(@Param("page") Page page, @Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + /** + * 查询项目变更申请列表 + * + * @param queryWrapper 条件 + * @return 项目变更申请集合 + */ + @DataPermission({ + @DataColumn(key = "deptName", value = "t.create_dept"), + @DataColumn(key = "userName", value = "t.create_by") + }) + public List selectCustomErpProjectChangeVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + /** + * 根据ID查询项目变更申请详情 + * + * @param projectChangeId 主键ID + * @return 项目变更申请对象 + */ + ErpProjectChangeVo selectCustomErpProjectChangeVoById(@Param("projectChangeId") Long projectChangeId); + + /** + * 根据ID列表批量查询项目变更申请 + * + * @param ids ID集合 + * @return 项目变更申请集合 + */ + List selectCustomErpProjectChangeVoByIds(@Param("ids") Collection ids); + + /** + * 统计项目变更申请记录数 + * + * @param queryWrapper 查询条件 + * @return 记录总数 + */ + Long countCustomErpProjectChange(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 分页查询项目变更申请(自定义条件) + * + * @param page 分页对象 + * @param queryWrapper 查询条件 + * @return 分页结果 + */ + Page selectCustomErpProjectChangeVoPage(@Param("page") Page page, @Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 批量插入项目变更申请 + * + * @param list 项目变更申请对象集合 + * @return 影响行数 + */ + int batchInsertErpProjectChange(@Param("list") List list); + + /** + * 批量更新项目变更申请 + * + * @param list 项目变更申请对象集合 + * @return 影响行数 + */ + int batchUpdateErpProjectChange(@Param("list") List list); + + /** + * 根据自定义条件删除项目变更申请 + * + * @param queryWrapper 删除条件 + * @return 影响行数 + */ + int deleteCustomErpProjectChange(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 根据ID列表批量删除项目变更申请 + * + * @param ids ID集合 + * @return 影响行数 + */ + int deleteCustomErpProjectChangeByIds(@Param("ids") Collection ids); + + /** + * 检查项目变更申请是否存在 + * + * @param queryWrapper 查询条件 + * @return 是否存在 + */ + Boolean existsErpProjectChange(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 根据项目ID准备项目变更信息(带出项目信息和用户名称) + * + * @param projectId 项目ID + * @return 项目变更申请对象 + */ + ErpProjectChangeVo prepareByProjectId(@Param("projectId") Long projectId); + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectChangeProgressMapper.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectChangeProgressMapper.java new file mode 100644 index 00000000..4e7e2356 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectChangeProgressMapper.java @@ -0,0 +1,113 @@ +package org.dromara.oa.erp.mapper; + +import java.util.List; +import java.util.Collection; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; +import org.dromara.oa.erp.domain.ErpProjectChangeProgress; +import org.dromara.oa.erp.domain.vo.ErpProjectChangeProgressVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 项目进度变更明细Mapper接口 + * + * @author Yinq + * @date 2025-11-10 + */ +public interface ErpProjectChangeProgressMapper extends BaseMapperPlus { + + /** + * 查询项目进度变更明细列表 + * + * @param page 分页 + * @param queryWrapper 条件 + * @return 项目进度变更明细集合 + */ + public Page selectCustomErpProjectChangeProgressVoList(@Param("page") Page page, @Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + /** + * 查询项目进度变更明细列表 + * + * @param queryWrapper 条件 + * @return 项目进度变更明细集合 + */ + public List selectCustomErpProjectChangeProgressVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + /** + * 根据ID查询项目进度变更明细详情 + * + * @param changeProgressId 主键ID + * @return 项目进度变更明细对象 + */ + ErpProjectChangeProgressVo selectCustomErpProjectChangeProgressVoById(@Param("changeProgressId") Long changeProgressId); + + /** + * 根据ID列表批量查询项目进度变更明细 + * + * @param ids ID集合 + * @return 项目进度变更明细集合 + */ + List selectCustomErpProjectChangeProgressVoByIds(@Param("ids") Collection ids); + + /** + * 统计项目进度变更明细记录数 + * + * @param queryWrapper 查询条件 + * @return 记录总数 + */ + Long countCustomErpProjectChangeProgress(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 分页查询项目进度变更明细(自定义条件) + * + * @param page 分页对象 + * @param queryWrapper 查询条件 + * @return 分页结果 + */ + Page selectCustomErpProjectChangeProgressVoPage(@Param("page") Page page, @Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 批量插入项目进度变更明细 + * + * @param list 项目进度变更明细对象集合 + * @return 影响行数 + */ + int batchInsertErpProjectChangeProgress(@Param("list") List list); + + /** + * 批量更新项目进度变更明细 + * + * @param list 项目进度变更明细对象集合 + * @return 影响行数 + */ + int batchUpdateErpProjectChangeProgress(@Param("list") List list); + + /** + * 根据自定义条件删除项目进度变更明细 + * + * @param queryWrapper 删除条件 + * @return 影响行数 + */ + int deleteCustomErpProjectChangeProgress(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 根据ID列表批量删除项目进度变更明细 + * + * @param ids ID集合 + * @return 影响行数 + */ + int deleteCustomErpProjectChangeProgressByIds(@Param("ids") Collection ids); + + /** + * 检查项目进度变更明细是否存在 + * + * @param queryWrapper 查询条件 + * @return 是否存在 + */ + Boolean existsErpProjectChangeProgress(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectChangeBudgetService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectChangeBudgetService.java new file mode 100644 index 00000000..5c882beb --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectChangeBudgetService.java @@ -0,0 +1,69 @@ +package org.dromara.oa.erp.service; + +import org.dromara.oa.erp.domain.ErpProjectChangeBudget; +import org.dromara.oa.erp.domain.vo.ErpProjectChangeBudgetVo; +import org.dromara.oa.erp.domain.bo.ErpProjectChangeBudgetBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 项目预算变更明细Service接口 + * + * @author Yinq + * @date 2025-11-10 + */ +public interface IErpProjectChangeBudgetService { + + /** + * 查询项目预算变更明细 + * + * @param changeBudgetId 主键 + * @return 项目预算变更明细 + */ + ErpProjectChangeBudgetVo queryById(Long changeBudgetId); + + /** + * 分页查询项目预算变更明细列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目预算变更明细分页列表 + */ + TableDataInfo queryPageList(ErpProjectChangeBudgetBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的项目预算变更明细列表 + * + * @param bo 查询条件 + * @return 项目预算变更明细列表 + */ + List queryList(ErpProjectChangeBudgetBo bo); + + /** + * 新增项目预算变更明细 + * + * @param bo 项目预算变更明细 + * @return 是否新增成功 + */ + Boolean insertByBo(ErpProjectChangeBudgetBo bo); + + /** + * 修改项目预算变更明细 + * + * @param bo 项目预算变更明细 + * @return 是否修改成功 + */ + Boolean updateByBo(ErpProjectChangeBudgetBo bo); + + /** + * 校验并批量删除项目预算变更明细信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectChangeProgressService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectChangeProgressService.java new file mode 100644 index 00000000..91a09826 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectChangeProgressService.java @@ -0,0 +1,69 @@ +package org.dromara.oa.erp.service; + +import org.dromara.oa.erp.domain.ErpProjectChangeProgress; +import org.dromara.oa.erp.domain.vo.ErpProjectChangeProgressVo; +import org.dromara.oa.erp.domain.bo.ErpProjectChangeProgressBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 项目进度变更明细Service接口 + * + * @author Yinq + * @date 2025-11-10 + */ +public interface IErpProjectChangeProgressService { + + /** + * 查询项目进度变更明细 + * + * @param changeProgressId 主键 + * @return 项目进度变更明细 + */ + ErpProjectChangeProgressVo queryById(Long changeProgressId); + + /** + * 分页查询项目进度变更明细列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目进度变更明细分页列表 + */ + TableDataInfo queryPageList(ErpProjectChangeProgressBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的项目进度变更明细列表 + * + * @param bo 查询条件 + * @return 项目进度变更明细列表 + */ + List queryList(ErpProjectChangeProgressBo bo); + + /** + * 新增项目进度变更明细 + * + * @param bo 项目进度变更明细 + * @return 是否新增成功 + */ + Boolean insertByBo(ErpProjectChangeProgressBo bo); + + /** + * 修改项目进度变更明细 + * + * @param bo 项目进度变更明细 + * @return 是否修改成功 + */ + Boolean updateByBo(ErpProjectChangeProgressBo bo); + + /** + * 校验并批量删除项目进度变更明细信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectChangeService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectChangeService.java new file mode 100644 index 00000000..d51736a7 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectChangeService.java @@ -0,0 +1,85 @@ +package org.dromara.oa.erp.service; + +import org.dromara.oa.erp.domain.ErpProjectChange; +import org.dromara.oa.erp.domain.vo.ErpProjectChangeVo; +import org.dromara.oa.erp.domain.bo.ErpProjectChangeBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 项目变更申请Service接口 + * + * @author Yinq + * @date 2025-11-10 + */ +public interface IErpProjectChangeService { + + /** + * 查询项目变更申请 + * + * @param projectChangeId 主键 + * @return 项目变更申请 + */ + ErpProjectChangeVo queryById(Long projectChangeId); + + /** + * 分页查询项目变更申请列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目变更申请分页列表 + */ + TableDataInfo queryPageList(ErpProjectChangeBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的项目变更申请列表 + * + * @param bo 查询条件 + * @return 项目变更申请列表 + */ + List queryList(ErpProjectChangeBo bo); + + /** + * 新增项目变更申请 + * + * @param bo 项目变更申请 + * @return 是否新增成功 + */ + Boolean insertByBo(ErpProjectChangeBo bo); + + /** + * 修改项目变更申请 + * + * @param bo 项目变更申请 + * @return 是否修改成功 + */ + Boolean updateByBo(ErpProjectChangeBo bo); + + /** + * 校验并批量删除项目变更申请信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 根据项目 ID 准备项目变更信息(带出项目信息和项目计划阶段) + * + * @param projectId 项目 ID + * @return 项目变更信息 + */ + ErpProjectChangeVo prepareByProjectWithInfo(Long projectId); + + /** + * 提交项目变更并发起审批流 + * + * @param bo 项目变更申请 + * @return 是否成功 + */ + ErpProjectChangeVo projectChangeSubmitAndFlowStart(ErpProjectChangeBo bo); +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectChangeBudgetServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectChangeBudgetServiceImpl.java new file mode 100644 index 00000000..e99d253c --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectChangeBudgetServiceImpl.java @@ -0,0 +1,139 @@ +package org.dromara.oa.erp.service.impl; + +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; + import org.dromara.common.mybatis.core.page.TableDataInfo; + import org.dromara.common.mybatis.core.page.PageQuery; + import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.github.yulichang.toolkit.JoinWrappers; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.dromara.oa.erp.domain.bo.ErpProjectChangeBudgetBo; +import org.dromara.oa.erp.domain.vo.ErpProjectChangeBudgetVo; +import org.dromara.oa.erp.domain.ErpProjectChangeBudget; +import org.dromara.oa.erp.mapper.ErpProjectChangeBudgetMapper; +import org.dromara.oa.erp.service.IErpProjectChangeBudgetService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 项目预算变更明细Service业务层处理 + * + * @author Yinq + * @date 2025-11-10 + */ +@RequiredArgsConstructor +@Service +public class ErpProjectChangeBudgetServiceImpl implements IErpProjectChangeBudgetService { + + private final ErpProjectChangeBudgetMapper baseMapper; + + /** + * 查询项目预算变更明细 + * + * @param changeBudgetId 主键 + * @return 项目预算变更明细 + */ + @Override + public ErpProjectChangeBudgetVo queryById(Long changeBudgetId){ + return baseMapper.selectVoById(changeBudgetId); + } + + /** + * 分页查询项目预算变更明细列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目预算变更明细分页列表 + */ + @Override + public TableDataInfo queryPageList(ErpProjectChangeBudgetBo bo, PageQuery pageQuery) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的项目预算变更明细列表 + * + * @param bo 查询条件 + * @return 项目预算变更明细列表 + */ + @Override + public List queryList(ErpProjectChangeBudgetBo bo) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private MPJLambdaWrapper buildQueryWrapper(ErpProjectChangeBudgetBo bo) { + Map params = bo.getParams(); + MPJLambdaWrapper lqw = JoinWrappers.lambda(ErpProjectChangeBudget.class) + .selectAll(ErpProjectChangeBudget.class) + .eq(ErpProjectChangeBudget::getDelFlag, "0") + .eq(bo.getProjectChangeId() != null, ErpProjectChangeBudget::getProjectChangeId, bo.getProjectChangeId()) + .eq(bo.getBudgetDetailId() != null, ErpProjectChangeBudget::getBudgetDetailId, bo.getBudgetDetailId()) + .like(StringUtils.isNotBlank(bo.getSubjectName()), ErpProjectChangeBudget::getSubjectName, bo.getSubjectName()) + .eq(bo.getBudgetBefore() != null, ErpProjectChangeBudget::getBudgetBefore, bo.getBudgetBefore()) + .eq(bo.getBudgetAfter() != null, ErpProjectChangeBudget::getBudgetAfter, bo.getBudgetAfter()) + .eq(bo.getAmountUsed() != null, ErpProjectChangeBudget::getAmountUsed, bo.getAmountUsed()) + .eq(StringUtils.isNotBlank(bo.getAdjustmentReason()), ErpProjectChangeBudget::getAdjustmentReason, bo.getAdjustmentReason()) + .eq(bo.getSortOrder() != null, ErpProjectChangeBudget::getSortOrder, bo.getSortOrder()); + return lqw; + } + + /** + * 新增项目预算变更明细 + * + * @param bo 项目预算变更明细 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(ErpProjectChangeBudgetBo bo) { + ErpProjectChangeBudget add = MapstructUtils.convert(bo, ErpProjectChangeBudget.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setChangeBudgetId(add.getChangeBudgetId()); + } + return flag; + } + + /** + * 修改项目预算变更明细 + * + * @param bo 项目预算变更明细 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(ErpProjectChangeBudgetBo bo) { + ErpProjectChangeBudget update = MapstructUtils.convert(bo, ErpProjectChangeBudget.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(ErpProjectChangeBudget entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除项目预算变更明细信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectChangeProgressServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectChangeProgressServiceImpl.java new file mode 100644 index 00000000..101eac47 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectChangeProgressServiceImpl.java @@ -0,0 +1,140 @@ +package org.dromara.oa.erp.service.impl; + +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; + import org.dromara.common.mybatis.core.page.TableDataInfo; + import org.dromara.common.mybatis.core.page.PageQuery; + import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.github.yulichang.toolkit.JoinWrappers; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.dromara.oa.erp.domain.bo.ErpProjectChangeProgressBo; +import org.dromara.oa.erp.domain.vo.ErpProjectChangeProgressVo; +import org.dromara.oa.erp.domain.ErpProjectChangeProgress; +import org.dromara.oa.erp.mapper.ErpProjectChangeProgressMapper; +import org.dromara.oa.erp.service.IErpProjectChangeProgressService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 项目进度变更明细Service业务层处理 + * + * @author Yinq + * @date 2025-11-10 + */ +@RequiredArgsConstructor +@Service +public class ErpProjectChangeProgressServiceImpl implements IErpProjectChangeProgressService { + + private final ErpProjectChangeProgressMapper baseMapper; + + /** + * 查询项目进度变更明细 + * + * @param changeProgressId 主键 + * @return 项目进度变更明细 + */ + @Override + public ErpProjectChangeProgressVo queryById(Long changeProgressId){ + return baseMapper.selectVoById(changeProgressId); + } + + /** + * 分页查询项目进度变更明细列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目进度变更明细分页列表 + */ + @Override + public TableDataInfo queryPageList(ErpProjectChangeProgressBo bo, PageQuery pageQuery) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的项目进度变更明细列表 + * + * @param bo 查询条件 + * @return 项目进度变更明细列表 + */ + @Override + public List queryList(ErpProjectChangeProgressBo bo) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private MPJLambdaWrapper buildQueryWrapper(ErpProjectChangeProgressBo bo) { + Map params = bo.getParams(); + MPJLambdaWrapper lqw = JoinWrappers.lambda(ErpProjectChangeProgress.class) + .selectAll(ErpProjectChangeProgress.class) + .eq(ErpProjectChangeProgress::getDelFlag, "0") + .eq(bo.getProjectChangeId() != null, ErpProjectChangeProgress::getProjectChangeId, bo.getProjectChangeId()) + .eq(bo.getPlanStageId() != null, ErpProjectChangeProgress::getPlanStageId, bo.getPlanStageId()) + .like(StringUtils.isNotBlank(bo.getMilestoneName()), ErpProjectChangeProgress::getMilestoneName, bo.getMilestoneName()) + .eq(bo.getOriginalStart() != null, ErpProjectChangeProgress::getOriginalStart, bo.getOriginalStart()) + .eq(bo.getOriginalEnd() != null, ErpProjectChangeProgress::getOriginalEnd, bo.getOriginalEnd()) + .eq(bo.getChangedStart() != null, ErpProjectChangeProgress::getChangedStart, bo.getChangedStart()) + .eq(bo.getChangedEnd() != null, ErpProjectChangeProgress::getChangedEnd, bo.getChangedEnd()) + .eq(bo.getCompletionDegree() != null, ErpProjectChangeProgress::getCompletionDegree, bo.getCompletionDegree()) + .eq(bo.getSortOrder() != null, ErpProjectChangeProgress::getSortOrder, bo.getSortOrder()); + return lqw; + } + + /** + * 新增项目进度变更明细 + * + * @param bo 项目进度变更明细 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(ErpProjectChangeProgressBo bo) { + ErpProjectChangeProgress add = MapstructUtils.convert(bo, ErpProjectChangeProgress.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setChangeProgressId(add.getChangeProgressId()); + } + return flag; + } + + /** + * 修改项目进度变更明细 + * + * @param bo 项目进度变更明细 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(ErpProjectChangeProgressBo bo) { + ErpProjectChangeProgress update = MapstructUtils.convert(bo, ErpProjectChangeProgress.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(ErpProjectChangeProgress entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除项目进度变更明细信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectChangeServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectChangeServiceImpl.java new file mode 100644 index 00000000..f1070935 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectChangeServiceImpl.java @@ -0,0 +1,445 @@ +package org.dromara.oa.erp.service.impl; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.map.MapUtil; +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.enums.OAStatusEnum; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.ObjectUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +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.*; +import org.dromara.oa.erp.mapper.*; +import org.dromara.workflow.api.RemoteWorkflowService; +import org.dromara.workflow.api.domain.RemoteStartProcess; +import org.dromara.workflow.api.event.ProcessEvent; +import org.springframework.context.event.EventListener; +import org.dromara.common.satoken.utils.LoginHelper; +import org.springframework.stereotype.Service; +import org.dromara.oa.erp.domain.bo.ErpProjectChangeBo; +import org.dromara.oa.erp.domain.vo.ErpProjectChangeVo; +import org.dromara.oa.erp.service.IErpProjectChangeService; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 项目变更申请Service业务层处理 + * + * @author Yinq + * @date 2025-11-10 + */ +@RequiredArgsConstructor +@Service +@Slf4j +public class ErpProjectChangeServiceImpl implements IErpProjectChangeService { + + private final ErpProjectChangeMapper baseMapper; + private final ErpProjectChangeBudgetMapper changeBudgetMapper; + private final ErpProjectChangeProgressMapper changeProgressMapper; + private final ErpProjectInfoMapper projectInfoMapper; + private final ErpProjectPlanMapper projectPlanMapper; + private final ErpProjectPlanStageMapper planStageMapper; + + @DubboReference(timeout = 30000) + private RemoteWorkflowService remoteWorkflowService; + + /** + * 查询项目变更申请 + * + * @param projectChangeId 主键 + * @return 项目变更申请 + */ + @Override + public ErpProjectChangeVo queryById(Long projectChangeId){ + // 使用自定义查询方法,连表查询用户名称 + ErpProjectChangeVo projectChangeVo = baseMapper.selectCustomErpProjectChangeVoById(projectChangeId); + if (ObjectUtils.isEmpty(projectChangeVo)) { + return null; + } + // 查询预算变更明细列表 + MPJLambdaWrapper budgetLqw = JoinWrappers.lambda(ErpProjectChangeBudget.class) + .selectAll(ErpProjectChangeBudget.class) + .eq("t.del_flag", "0") + .eq(projectChangeId != null, ErpProjectChangeBudget::getProjectChangeId, projectChangeId); + List budgetList = changeBudgetMapper.selectList(budgetLqw); + projectChangeVo.setBudgetList(budgetList); + + // 查询进度变更明细列表,连表查询项目计划阶段获取projectPhases + MPJLambdaWrapper progressLqw = JoinWrappers.lambda(ErpProjectChangeProgress.class) + .selectAll(ErpProjectChangeProgress.class) + .selectAs(ErpProjectPlanStage::getProjectPhases, ErpProjectChangeProgress::getProjectPhases) + .leftJoin(ErpProjectPlanStage.class, ErpProjectPlanStage::getPlanStageId, ErpProjectChangeProgress::getPlanStageId) + .eq("t.del_flag", "0") + .eq(projectChangeId != null, ErpProjectChangeProgress::getProjectChangeId, projectChangeId) + .orderByAsc(ErpProjectChangeProgress::getSortOrder); + List progressList = changeProgressMapper.selectList(progressLqw); + projectChangeVo.setProgressList(progressList); + + return projectChangeVo; + } + + /** + * 分页查询项目变更申请列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目变更申请分页列表 + */ + @Override + public TableDataInfo queryPageList(ErpProjectChangeBo bo, PageQuery pageQuery) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的项目变更申请列表 + * + * @param bo 查询条件 + * @return 项目变更申请列表 + */ + @Override + public List queryList(ErpProjectChangeBo bo) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private MPJLambdaWrapper buildQueryWrapper(ErpProjectChangeBo bo) { + Map params = bo.getParams(); + MPJLambdaWrapper lqw = JoinWrappers.lambda(ErpProjectChange.class) + .selectAll(ErpProjectChange.class) + .eq(ErpProjectChange::getDelFlag, "0") + .eq(bo.getProjectId() != null, ErpProjectChange::getProjectId, bo.getProjectId()) + .eq(StringUtils.isNotBlank(bo.getProjectCode()), ErpProjectChange::getProjectCode, bo.getProjectCode()) + .like(StringUtils.isNotBlank(bo.getProjectName()), ErpProjectChange::getProjectName, bo.getProjectName()) + .eq(StringUtils.isNotBlank(bo.getProjectCategory()), ErpProjectChange::getProjectCategory, bo.getProjectCategory()) + .eq(StringUtils.isNotBlank(bo.getChangeType()), ErpProjectChange::getChangeType, bo.getChangeType()) + .eq(bo.getChangeNumber() != null, ErpProjectChange::getChangeNumber, bo.getChangeNumber()) + .eq(bo.getProjectManagerId() != null, ErpProjectChange::getProjectManagerId, bo.getProjectManagerId()) + .like(StringUtils.isNotBlank(bo.getProjectManagerName()), ErpProjectChange::getProjectManagerName, bo.getProjectManagerName()) + .eq(bo.getDeptHeadId() != null, ErpProjectChange::getDeptHeadId, bo.getDeptHeadId()) + .like(StringUtils.isNotBlank(bo.getDeptHeadName()), ErpProjectChange::getDeptHeadName, bo.getDeptHeadName()) + .eq(bo.getResponsibleVpId() != null, ErpProjectChange::getResponsibleVpId, bo.getResponsibleVpId()) + .like(StringUtils.isNotBlank(bo.getResponsibleVpName()), ErpProjectChange::getResponsibleVpName, bo.getResponsibleVpName()) + .eq(bo.getApplyChangeDate() != null, ErpProjectChange::getApplyChangeDate, bo.getApplyChangeDate()) + .eq(bo.getContractAmount() != null, ErpProjectChange::getContractAmount, bo.getContractAmount()) + .eq(bo.getContractNetAmount() != null, ErpProjectChange::getContractNetAmount, bo.getContractNetAmount()) + .eq(StringUtils.isNotBlank(bo.getCurrentStatus()), ErpProjectChange::getCurrentStatus, bo.getCurrentStatus()) + .eq(StringUtils.isNotBlank(bo.getChangeReason()), ErpProjectChange::getChangeReason, bo.getChangeReason()) + .eq(StringUtils.isNotBlank(bo.getFollowUpWork()), ErpProjectChange::getFollowUpWork, bo.getFollowUpWork()) + .eq(StringUtils.isNotBlank(bo.getProjectChangeStatus()), ErpProjectChange::getProjectChangeStatus, bo.getProjectChangeStatus()) + .eq(StringUtils.isNotBlank(bo.getFlowStatus()), ErpProjectChange::getFlowStatus, bo.getFlowStatus()) + .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectChange::getActiveFlag, bo.getActiveFlag()) +; + return lqw; + } + + /** + * 新增项目变更申请 + * + * @param bo 项目变更申请 + * @return 是否新增成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean insertByBo(ErpProjectChangeBo bo) { + ErpProjectChange add = MapstructUtils.convert(bo, ErpProjectChange.class); + validEntityBeforeSave(add); + + List budgetList = bo.getBudgetList(); + List progressList = bo.getProgressList(); + + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setProjectChangeId(add.getProjectChangeId()); + + // 保存预算变更明细 + if (ObjectUtils.isNotEmpty(budgetList)) { + for (ErpProjectChangeBudget budget : budgetList) { + budget.setProjectChangeId(add.getProjectChangeId()); + changeBudgetMapper.insert(budget); + } + } + + // 保存进度变更明细 + if (ObjectUtils.isNotEmpty(progressList)) { + for (ErpProjectChangeProgress progress : progressList) { + progress.setProjectChangeId(add.getProjectChangeId()); + changeProgressMapper.insert(progress); + } + } + } + return flag; + } + + /** + * 修改项目变更申请 + * + * @param bo 项目变更申请 + * @return 是否修改成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateByBo(ErpProjectChangeBo bo) { + ErpProjectChange update = MapstructUtils.convert(bo, ErpProjectChange.class); + validEntityBeforeSave(update); + + List budgetList = bo.getBudgetList(); + List progressList = bo.getProgressList(); + + // 处理预算变更明细 + if (budgetList != null && !budgetList.isEmpty()) { + for (ErpProjectChangeBudget budget : budgetList) { + budget.setProjectChangeId(bo.getProjectChangeId()); + changeBudgetMapper.insertOrUpdate(budget); + } + // 删除前端未提交的旧数据 + Set existingBudgetIds = budgetList.stream() + .map(ErpProjectChangeBudget::getChangeBudgetId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + MPJLambdaWrapper budgetLqw = JoinWrappers.lambda(ErpProjectChangeBudget.class); + budgetLqw.eq(ErpProjectChangeBudget::getProjectChangeId, bo.getProjectChangeId()); + List oldBudgetList = changeBudgetMapper.selectList(budgetLqw); + oldBudgetList.stream() + .filter(budget -> !existingBudgetIds.contains(budget.getChangeBudgetId())) + .forEach(budget -> changeBudgetMapper.deleteById(budget.getChangeBudgetId())); + } + + // 处理进度变更明细 + if (progressList != null && !progressList.isEmpty()) { + for (ErpProjectChangeProgress progress : progressList) { + progress.setProjectChangeId(bo.getProjectChangeId()); + changeProgressMapper.insertOrUpdate(progress); + } + // 删除前端未提交的旧数据 + Set existingProgressIds = progressList.stream() + .map(ErpProjectChangeProgress::getChangeProgressId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + MPJLambdaWrapper progressLqw = JoinWrappers.lambda(ErpProjectChangeProgress.class); + progressLqw.eq(ErpProjectChangeProgress::getProjectChangeId, bo.getProjectChangeId()); + List oldProgressList = changeProgressMapper.selectList(progressLqw); + oldProgressList.stream() + .filter(progress -> !existingProgressIds.contains(progress.getChangeProgressId())) + .forEach(progress -> changeProgressMapper.deleteById(progress.getChangeProgressId())); + } + + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(ErpProjectChange entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除项目变更申请信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + @GlobalTransactional(rollbackFor = Exception.class) + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + // 先删除子表 + changeBudgetMapper.delete(Wrappers.lambdaQuery().in(ErpProjectChangeBudget::getProjectChangeId, ids)); + changeProgressMapper.delete(Wrappers.lambdaQuery().in(ErpProjectChangeProgress::getProjectChangeId, ids)); + // 删除主表 + baseMapper.deleteByIds(ids); + //删除工作流 + List businessIds = ids.stream().toList(); + return remoteWorkflowService.deleteInstance(businessIds); + } + + /** + * 根据项目 ID 准备项目变更信息(带出项目信息和项目计划阶段) + * + * @param projectId 项目 ID + * @return 项目变更信息 + */ + @Override + public ErpProjectChangeVo prepareByProjectWithInfo(Long projectId) { + if (projectId == null) { + throw new ServiceException("项目ID不能为空"); + } + + // 若存在审批中的项目变更则禁止再次发起 + long approvingCount = baseMapper.selectCount(Wrappers.lambdaQuery() + .eq(ErpProjectChange::getProjectId, projectId) + .eq(ErpProjectChange::getDelFlag, "0") + .eq(ErpProjectChange::getProjectChangeStatus, OAStatusEnum.APPROVING.getStatus()));// "2"审批中,"3"可用 + if (approvingCount > 0) { + throw new ServiceException("该项目存在未完成的变更申请,请等待审批完成后再发起新的变更"); + } + + // 如果已有暂存记录,返回该记录供继续编辑 + ErpProjectChange draftChange = baseMapper.selectOne(Wrappers.lambdaQuery() + .eq(ErpProjectChange::getProjectId, projectId) + .eq(ErpProjectChange::getDelFlag, "0") + .eq(ErpProjectChange::getProjectChangeStatus, "1") + .orderByDesc(ErpProjectChange::getCreateTime) + .last("limit 1")); + if (draftChange != null) { + return queryById(draftChange.getProjectChangeId()); + } + + // 通过自定义Mapper方法查询项目信息和用户名称(连表查询sys_user) + ErpProjectChangeVo vo = baseMapper.prepareByProjectId(projectId); + if (vo == null) { + throw new ServiceException("项目不存在"); + } + + // 查询项目计划信息 + MPJLambdaWrapper planLqw = JoinWrappers.lambda(ErpProjectPlan.class) + .eq(ErpProjectPlan::getProjectId, projectId) + .eq(ErpProjectPlan::getDelFlag, "0"); + ErpProjectPlan projectPlan = projectPlanMapper.selectOne(planLqw); + + if (projectPlan != null) { + // 查询项目计划阶段 + MPJLambdaWrapper stageLqw = JoinWrappers.lambda(ErpProjectPlanStage.class) + .eq(ErpProjectPlanStage::getProjectPlanId, projectPlan.getProjectPlanId()) + .eq(ErpProjectPlanStage::getDelFlag, "0") + .orderByAsc(ErpProjectPlanStage::getSortOrder); + List planStageList = planStageMapper.selectList(stageLqw); + + // 将项目阶段转换为进度变更明细 + if (ObjectUtils.isNotEmpty(planStageList)) { + List progressList = planStageList.stream().map(stage -> { + ErpProjectChangeProgress progress = new ErpProjectChangeProgress(); + progress.setPlanStageId(stage.getPlanStageId()); // 绑定项目计划阶段ID + progress.setProjectPhases(stage.getProjectPhases()); // 项目阶段字典值(禁用显示) + progress.setMilestoneName(""); // 里程碑名称由用户手动输入 + progress.setOriginalStart(stage.getPlanStartTime()); // 原计划开始时间 + progress.setOriginalEnd(stage.getPlanEndTime()); // 原计划结束时间 + progress.setChangedStart(stage.getPlanStartTime()); // 初始值设为原计划时间 + progress.setChangedEnd(stage.getPlanEndTime()); // 初始值设为原计划时间 + progress.setSortOrder(stage.getSortOrder()); // 排序顺序 + return progress; + }).collect(Collectors.toList()); + vo.setProgressList(progressList); + } + } + + // 初始化空的预算变更列表(由用户手动添加) + vo.setBudgetList(new ArrayList<>()); + + // 计算变更次数:查询该项目已完成的变更次数 + MPJLambdaWrapper changeCountLqw = JoinWrappers.lambda(ErpProjectChange.class) + .eq(ErpProjectChange::getProjectId, projectId) + .eq(ErpProjectChange::getDelFlag, "0") + .eq(ErpProjectChange::getProjectChangeStatus, OAStatusEnum.COMPLETED.getStatus()); + int changeCount = Math.toIntExact(baseMapper.selectCount(changeCountLqw)); + + vo.setChangeNumber(changeCount + 1); // 当前变更次数 = 已有次数 + 1 + + // 设置默认值 + vo.setActiveFlag("1"); + vo.setProjectChangeStatus("1"); // 1-暂存 + + return vo; + } + + /** + * 提交项目变更并发起审批流 + * + * @param bo 项目变更申请 + * @return 是否成功 + */ + @Override + @GlobalTransactional(rollbackFor = Exception.class) + public ErpProjectChangeVo projectChangeSubmitAndFlowStart(ErpProjectChangeBo bo) { + + ErpProjectChange add = MapstructUtils.convert(bo, ErpProjectChange.class); + validEntityBeforeSave(add) ; + // 权限校验:只有项目经理才能提交 + validateProjectManager(bo.getProjectManagerId()); + + // 保存或更新项目变更数据 + boolean saveFlag; + if (bo.getProjectChangeId() == null) { + saveFlag = insertByBo(bo); + } else { + saveFlag = updateByBo(bo); + } + + if (!saveFlag) { + throw new ServiceException("保存项目变更失败"); + } + + // 后端发起需要忽略权限 + bo.getVariables().put("ignore", true); + RemoteStartProcess startProcess = new RemoteStartProcess(); + startProcess.setBusinessId(bo.getProjectChangeId().toString()); + startProcess.setFlowCode(bo.getFlowCode()); + startProcess.setVariables(bo.getVariables()); + startProcess.setBizExt(bo.getBizExt()); + bo.getBizExt().setBusinessId(startProcess.getBusinessId()); + boolean flagOne = remoteWorkflowService.startCompleteTask(startProcess); + if (!flagOne) { + throw new ServiceException("流程发起异常"); + } + + return MapstructUtils.convert(add, ErpProjectChangeVo.class); + } + + /** + * 项目变更流程监听器 + * + * @param processEvent 流程事件 + */ + @EventListener(condition = "#processEvent.flowCode == 'OAEP'") + public void processHandler(ProcessEvent processEvent) { + TenantHelper.dynamic(processEvent.getTenantId(), () -> { + ErpProjectChange projectChange = baseMapper.selectById(Convert.toLong(processEvent.getBusinessId())); + projectChange.setFlowStatus(processEvent.getStatus()); + Map params = processEvent.getParams(); + if (MapUtil.isNotEmpty( params)){ + // 办理人 + String handler = Convert.toStr(params.get("handler")); + } + if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())){ + projectChange.setProjectChangeStatus(OAStatusEnum.COMPLETED.getStatus()); + } + baseMapper.updateById(projectChange); + }); + } + + /** + * 校验项目经理权限 + * + * @param projectManagerId 项目经理ID + */ + private void validateProjectManager(Long projectManagerId) { + // 超级管理员跳过校验 + if (LoginHelper.isSuperAdmin()) { + return; + } + + Long currentUserId = LoginHelper.getUserId(); + if (!currentUserId.equals(projectManagerId)) { + throw new ServiceException("只有项目经理才能提交项目变更申请"); + } + } +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectChangeBudgetMapper.xml b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectChangeBudgetMapper.xml new file mode 100644 index 00000000..3ab6fbb0 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectChangeBudgetMapper.xml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + insert into erp_project_change_budget( + project_change_id, + + budget_detail_id, + + subject_name, + + budget_before, + + budget_after, + + amount_used, + + adjustment_reason, + + sort_order, + + remark, + + del_flag, + + create_dept, + + create_by, + + create_time, + + update_by, + + update_time + + ) + values + + ( + #{item.projectChangeId}, + + #{item.budgetDetailId}, + + #{item.subjectName}, + + #{item.budgetBefore}, + + #{item.budgetAfter}, + + #{item.amountUsed}, + + #{item.adjustmentReason}, + + #{item.sortOrder}, + + #{item.remark}, + + #{item.delFlag}, + + #{item.createDept}, + + #{item.createBy}, + + #{item.createTime}, + + #{item.updateBy}, + + #{item.updateTime} + + ) + + + + + + + update erp_project_change_budget + + + project_change_id = #{item.projectChangeId}, + + + budget_detail_id = #{item.budgetDetailId}, + + + subject_name = #{item.subjectName}, + + + budget_before = #{item.budgetBefore}, + + + budget_after = #{item.budgetAfter}, + + + amount_used = #{item.amountUsed}, + + + adjustment_reason = #{item.adjustmentReason}, + + + sort_order = #{item.sortOrder}, + + + remark = #{item.remark}, + + + del_flag = #{item.delFlag}, + + + create_dept = #{item.createDept}, + + + create_by = #{item.createBy}, + + + create_time = #{item.createTime}, + + + update_by = #{item.updateBy}, + + + update_time = #{item.updateTime} + + + where change_budget_id = #{item.changeBudgetId} + + + + + + delete from erp_project_change_budget + ${ew.getCustomSqlSegment} + + + + + delete from erp_project_change_budget + where change_budget_id in + + #{id} + + + + + + + + diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectChangeMapper.xml b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectChangeMapper.xml new file mode 100644 index 00000000..d9e7e207 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectChangeMapper.xml @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + insert into erp_project_change( + tenant_id, + + project_id, + + project_code, + + project_name, + + project_category, + + change_type, + + change_number, + + project_manager_id, + + project_manager_name, + + dept_head_id, + + dept_head_name, + + responsible_vp_id, + + responsible_vp_name, + + apply_change_date, + + contract_amount, + + contract_net_amount, + + current_status, + + change_reason, + + follow_up_work, + + project_change_status, + + flow_status, + + remark, + + active_flag, + + del_flag, + + create_dept, + + create_by, + + create_time, + + update_by, + + update_time + + ) + values + + ( + #{item.tenantId}, + + #{item.projectId}, + + #{item.projectCode}, + + #{item.projectName}, + + #{item.projectCategory}, + + #{item.changeType}, + + #{item.changeNumber}, + + #{item.projectManagerId}, + + #{item.projectManagerName}, + + #{item.deptHeadId}, + + #{item.deptHeadName}, + + #{item.responsibleVpId}, + + #{item.responsibleVpName}, + + #{item.applyChangeDate}, + + #{item.contractAmount}, + + #{item.contractNetAmount}, + + #{item.currentStatus}, + + #{item.changeReason}, + + #{item.followUpWork}, + + #{item.projectChangeStatus}, + + #{item.flowStatus}, + + #{item.remark}, + + #{item.activeFlag}, + + #{item.delFlag}, + + #{item.createDept}, + + #{item.createBy}, + + #{item.createTime}, + + #{item.updateBy}, + + #{item.updateTime} + + ) + + + + + + + update erp_project_change + + + tenant_id = #{item.tenantId}, + + + project_id = #{item.projectId}, + + + project_code = #{item.projectCode}, + + + project_name = #{item.projectName}, + + + project_category = #{item.projectCategory}, + + + change_type = #{item.changeType}, + + + change_number = #{item.changeNumber}, + + + project_manager_id = #{item.projectManagerId}, + + + project_manager_name = #{item.projectManagerName}, + + + dept_head_id = #{item.deptHeadId}, + + + dept_head_name = #{item.deptHeadName}, + + + responsible_vp_id = #{item.responsibleVpId}, + + + responsible_vp_name = #{item.responsibleVpName}, + + + apply_change_date = #{item.applyChangeDate}, + + + contract_amount = #{item.contractAmount}, + + + contract_net_amount = #{item.contractNetAmount}, + + + current_status = #{item.currentStatus}, + + + change_reason = #{item.changeReason}, + + + follow_up_work = #{item.followUpWork}, + + + project_change_status = #{item.projectChangeStatus}, + + + flow_status = #{item.flowStatus}, + + + remark = #{item.remark}, + + + active_flag = #{item.activeFlag}, + + + del_flag = #{item.delFlag}, + + + create_dept = #{item.createDept}, + + + create_by = #{item.createBy}, + + + create_time = #{item.createTime}, + + + update_by = #{item.updateBy}, + + + update_time = #{item.updateTime} + + + where project_change_id = #{item.projectChangeId} + + + + + + delete from erp_project_change + ${ew.getCustomSqlSegment} + + + + + delete from erp_project_change + where project_change_id in + + #{id} + + + + + + + + + + + diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectChangeProgressMapper.xml b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectChangeProgressMapper.xml new file mode 100644 index 00000000..bd47a671 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectChangeProgressMapper.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + insert into erp_project_change_progress( + project_change_id, + + plan_stage_id, + + milestone_name, + + original_start, + + original_end, + + changed_start, + + changed_end, + + completion_degree, + + sort_order, + + remark, + + del_flag, + + create_dept, + + create_by, + + create_time, + + update_by, + + update_time + + ) + values + + ( + #{item.projectChangeId}, + + #{item.planStageId}, + + #{item.milestoneName}, + + #{item.originalStart}, + + #{item.originalEnd}, + + #{item.changedStart}, + + #{item.changedEnd}, + + #{item.completionDegree}, + + #{item.sortOrder}, + + #{item.remark}, + + #{item.delFlag}, + + #{item.createDept}, + + #{item.createBy}, + + #{item.createTime}, + + #{item.updateBy}, + + #{item.updateTime} + + ) + + + + + + + update erp_project_change_progress + + + project_change_id = #{item.projectChangeId}, + + + plan_stage_id = #{item.planStageId}, + + + milestone_name = #{item.milestoneName}, + + + original_start = #{item.originalStart}, + + + original_end = #{item.originalEnd}, + + + changed_start = #{item.changedStart}, + + + changed_end = #{item.changedEnd}, + + + completion_degree = #{item.completionDegree}, + + + sort_order = #{item.sortOrder}, + + + remark = #{item.remark}, + + + del_flag = #{item.delFlag}, + + + create_dept = #{item.createDept}, + + + create_by = #{item.createBy}, + + + create_time = #{item.createTime}, + + + update_by = #{item.updateBy}, + + + update_time = #{item.updateTime} + + + where change_progress_id = #{item.changeProgressId} + + + + + + delete from erp_project_change_progress + ${ew.getCustomSqlSegment} + + + + + delete from erp_project_change_progress + where change_progress_id in + + #{id} + + + + + + + + diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/报价单模板.md b/ruoyi-modules/ruoyi-oa/src/main/resources/报价单模板.md new file mode 100644 index 00000000..a89b2473 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/resources/报价单模板.md @@ -0,0 +1,22 @@ +致: +{customerContactName} +{title} +报价日期 {quoteDate} +含税信息 {taxIncludedInfo} +付款方式 {paymentMethod} +交货期 {deliveryPeriod} +交货方式 {deliveryMethod} +报价有效期 {quoteValidity} + 币种:{currencyType} 价格单位:元 +序号 产品名称 型号/说明 数量 单位 单价 小计 备注 +{data.seq} {data.productName} {data.modelDesc} {data.quantity} {data.unit} {data.price} {data.subtotal} {data.remark} + +合计 {total} + 小写: {totalLower} 大写: {totalUpper} +注: +"供货方信息: +公司名称:青岛海威物联科技有限公司 +公司地址:青岛市市北区郑州路43号 +公司网址:www.highwayiot.com " " 联 系 人: +联系电话: +电子邮件:" diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/报价单模板.xlsx b/ruoyi-modules/ruoyi-oa/src/main/resources/报价单模板.xlsx new file mode 100644 index 00000000..c448f1f5 Binary files /dev/null and b/ruoyi-modules/ruoyi-oa/src/main/resources/报价单模板.xlsx differ