feat(erp): 新增项目验收确认模块和项目收货

- 新增项目验收确认实体类ErpProjectAcceptance及相关BO和VO类
- 实现项目验收确认的增删改查接口及分页、导出功能
- 添加项目验收确认Mapper和XML,支持复杂查询、批量操作和逻辑删除
- 开发项目验收确认Service实现类,包含权限校验、流程发起、流程事件监听
- 控制器层增加验收准备、提交流程启动及权限校验等业务接口
- 完善验收确认信息关联项目经理、部门负责人、副总等用户信息展示
- 集成工作流API实现项目验收流程自动化管理
- 保证接口请求参数校验及幂等性处理,提高系统稳定性和安全性
dev
zangch@mesnac.com 3 months ago
parent fa85f7f2bc
commit a7db46bb22

@ -0,0 +1,136 @@
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.ErpProjectAcceptanceVo;
import org.dromara.oa.erp.domain.bo.ErpProjectAcceptanceBo;
import org.dromara.oa.erp.service.IErpProjectAcceptanceService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
*
* 访:/oa/erp/projectAcceptance
*
* @author Yinq
* @date 2025-11-12
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/erp/projectAcceptance")
public class ErpProjectAcceptanceController extends BaseController {
private final IErpProjectAcceptanceService erpProjectAcceptanceService;
/**
*
*/
@SaCheckPermission("oa/erp:projectAcceptance:list")
@GetMapping("/list")
public TableDataInfo<ErpProjectAcceptanceVo> list(ErpProjectAcceptanceBo bo, PageQuery pageQuery) {
return erpProjectAcceptanceService.queryPageList(bo, pageQuery);
}
/**
*
*/
@SaCheckPermission("oa/erp:projectAcceptance:export")
@Log(title = "项目验收确认", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ErpProjectAcceptanceBo bo, HttpServletResponse response) {
List<ErpProjectAcceptanceVo> list = erpProjectAcceptanceService.queryList(bo);
ExcelUtil.exportExcel(list, "项目验收确认", ErpProjectAcceptanceVo.class, response);
}
/**
*
*
* @param acceptanceId
*/
@SaCheckPermission("oa/erp:projectAcceptance:query")
@GetMapping("/{acceptanceId}")
public R<ErpProjectAcceptanceVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("acceptanceId") Long acceptanceId) {
return R.ok(erpProjectAcceptanceService.queryById(acceptanceId));
}
/**
*
*/
@SaCheckPermission("oa/erp:projectAcceptance:add")
@Log(title = "项目验收确认", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody ErpProjectAcceptanceBo bo) {
return toAjax(erpProjectAcceptanceService.insertByBo(bo));
}
/**
*
*/
@SaCheckPermission("oa/erp:projectAcceptance:edit")
@Log(title = "项目验收确认", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ErpProjectAcceptanceBo bo) {
return toAjax(erpProjectAcceptanceService.updateByBo(bo));
}
/**
*
*
* @param acceptanceIds
*/
@SaCheckPermission("oa/erp:projectAcceptance:remove")
@Log(title = "项目验收确认", businessType = BusinessType.DELETE)
@DeleteMapping("/{acceptanceIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] acceptanceIds) {
return toAjax(erpProjectAcceptanceService.deleteWithValidByIds(java.util.Arrays.asList(acceptanceIds), true));
}
/**
* ID
*/
@SaCheckPermission("oa/erp:projectAcceptance:query")
@GetMapping("/prepareByProjectId/{projectId}")
public R<ErpProjectAcceptanceVo> prepareByProjectId(@PathVariable Long projectId) {
return R.ok(erpProjectAcceptanceService.prepareByProjectId(projectId));
}
/**
*
*/
@SaCheckPermission("oa/erp:projectAcceptance:add")
@Log(title = "项目验收确认", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/submitAndFlowStart")
public R<ErpProjectAcceptanceVo> submitAndFlowStart(@Validated(AddGroup.class) @RequestBody ErpProjectAcceptanceBo bo) {
return R.ok(erpProjectAcceptanceService.submitAndFlowStart(bo));
}
/**
*
*/
@GetMapping("/getErpProjectAcceptanceList")
public R<List<ErpProjectAcceptanceVo>> getErpProjectAcceptanceList(ErpProjectAcceptanceBo bo) {
List<ErpProjectAcceptanceVo> list = erpProjectAcceptanceService.queryList(bo);
return R.ok(list);
}
}

@ -0,0 +1,136 @@
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.ErpProjectReceivingVo;
import org.dromara.oa.erp.domain.bo.ErpProjectReceivingBo;
import org.dromara.oa.erp.service.IErpProjectReceivingService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
*
* 访:/oa/erp/projectReceiving
*
* @author Yinq
* @date 2025-11-12
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/erp/projectReceiving")
public class ErpProjectReceivingController extends BaseController {
private final IErpProjectReceivingService erpProjectReceivingService;
/**
*
*/
@SaCheckPermission("oa/erp:projectReceiving:list")
@GetMapping("/list")
public TableDataInfo<ErpProjectReceivingVo> list(ErpProjectReceivingBo bo, PageQuery pageQuery) {
return erpProjectReceivingService.queryPageList(bo, pageQuery);
}
/**
*
*/
@SaCheckPermission("oa/erp:projectReceiving:export")
@Log(title = "项目收货确认", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ErpProjectReceivingBo bo, HttpServletResponse response) {
List<ErpProjectReceivingVo> list = erpProjectReceivingService.queryList(bo);
ExcelUtil.exportExcel(list, "项目收货确认", ErpProjectReceivingVo.class, response);
}
/**
*
*
* @param receivingId
*/
@SaCheckPermission("oa/erp:projectReceiving:query")
@GetMapping("/{receivingId}")
public R<ErpProjectReceivingVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("receivingId") Long receivingId) {
return R.ok(erpProjectReceivingService.queryById(receivingId));
}
/**
*
*/
@SaCheckPermission("oa/erp:projectReceiving:add")
@Log(title = "项目收货确认", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody ErpProjectReceivingBo bo) {
return toAjax(erpProjectReceivingService.insertByBo(bo));
}
/**
*
*/
@SaCheckPermission("oa/erp:projectReceiving:edit")
@Log(title = "项目收货确认", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ErpProjectReceivingBo bo) {
return toAjax(erpProjectReceivingService.updateByBo(bo));
}
/**
*
*
* @param receivingIds
*/
@SaCheckPermission("oa/erp:projectReceiving:remove")
@Log(title = "项目收货确认", businessType = BusinessType.DELETE)
@DeleteMapping("/{receivingIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] receivingIds) {
return toAjax(erpProjectReceivingService.deleteWithValidByIds(java.util.Arrays.asList(receivingIds), true));
}
/**
* ID
*/
@SaCheckPermission("oa/erp:projectReceiving:query")
@GetMapping("/prepareByProjectId/{projectId}")
public R<ErpProjectReceivingVo> prepareByProjectId(@PathVariable Long projectId) {
return R.ok(erpProjectReceivingService.prepareByProjectId(projectId));
}
/**
*
*/
@SaCheckPermission("oa/erp:projectReceiving:add")
@Log(title = "项目收货确认", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/submitAndFlowStart")
public R<ErpProjectReceivingVo> submitAndFlowStart(@Validated(AddGroup.class) @RequestBody ErpProjectReceivingBo bo) {
return R.ok(erpProjectReceivingService.submitAndFlowStart(bo));
}
/**
*
*/
@GetMapping("/getErpProjectReceivingList")
public R<List<ErpProjectReceivingVo>> getErpProjectReceivingList(ErpProjectReceivingBo bo) {
List<ErpProjectReceivingVo> list = erpProjectReceivingService.queryList(bo);
return R.ok(list);
}
}

@ -0,0 +1,118 @@
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.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
* erp_project_acceptance
*
* @author Yinq
* @date 2025-11-12
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_project_acceptance")
public class ErpProjectAcceptance extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "acceptance_id", type = IdType.ASSIGN_ID)
private Long acceptanceId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String projectCode;
/**
*
*/
private String projectName;
/**
*
*/
private Long managerId;
/**
*
*/
@TableField(exist = false)
private String projectManagerName;
/**
*
*/
private Date acceptanceDate;
/**
*
*/
private String ossId;
/**
*
*/
private Long chargeId;
/**
*
*/
private Long deputyId;
/**
*
*/
@TableField(exist = false)
private String chargeName;
/**
*
*/
@TableField(exist = false)
private String deputyName;
/**
*
*/
private String remark;
/**
*
*/
private String flowStatus;
/**
* (1 2 3)
*/
private String acceptanceStatus;
/**
* 0 1
*/
@TableLogic
private String delFlag;
/**
* acceptance_code
*/
@TableField("acceptance_code")
private String acceptanceCode;
}

@ -0,0 +1,118 @@
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.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
* erp_project_receiving
*
* @author Yinq
* @date 2025-11-12
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_project_receiving")
public class ErpProjectReceiving extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "receiving_id", type = IdType.ASSIGN_ID)
private Long receivingId;
/**
*
*/
private String projectCode;
/**
*
*/
private String projectName;
/**
* ID
*/
private Long projectId;
/**
*
*/
private Long managerId;
/**
*
*/
private Date arrivalDate;
/**
*
*/
private String ossId;
/**
*
*/
@TableField(exist = false)
private String projectManagerName;
/**
*
*/
private Long chargeId;
/**
*
*/
private Long deputyId;
/**
*
*/
@TableField(exist = false)
private String chargeName;
/**
*
*/
@TableField(exist = false)
private String deputyName;
/**
*
*/
private String remark;
/**
*
*/
private String flowStatus;
/**
* (1 2 3)
*/
private String receivingStatus;
/**
* 0 1
*/
@TableLogic
private String delFlag;
/**
* receiving_code
*/
@TableField("receiving_code")
private String receivingCode;
}

@ -0,0 +1,125 @@
package org.dromara.oa.erp.domain.bo;
import cn.hutool.core.util.ObjectUtil;
import org.dromara.oa.erp.domain.ErpProjectAcceptance;
import org.dromara.common.mybatis.core.domain.BaseEntity;
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.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt;
/**
* erp_project_acceptance
*
* @author Yinq
* @date 2025-11-12
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpProjectAcceptance.class, reverseConvertGenerate = false)
public class ErpProjectAcceptanceBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "验收确认ID不能为空", groups = { EditGroup.class })
private Long acceptanceId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String projectCode;
/**
*
*/
private String projectName;
/**
*
*/
private Long managerId;
/**
*
*/
private Date acceptanceDate;
/**
*
*/
private String ossId;
/**
* acceptance_code
*/
private String acceptanceCode;
/**
*
*/
private Long chargeId;
/**
*
*/
private Long deputyId;
/**
*
*/
private String remark;
/**
*
*/
private String flowCode;
/**
*
*/
private String handler;
/**
*
*/
private Map<String, Object> variables;
/**
*
*/
private RemoteFlowInstanceBizExt bizExt;
/**
* {'entity': {}}
*/
public Map<String, Object> 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;
}
}

@ -0,0 +1,122 @@
package org.dromara.oa.erp.domain.bo;
import cn.hutool.core.util.ObjectUtil;
import org.dromara.oa.erp.domain.ErpProjectReceiving;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt;
/**
* erp_project_receiving
*
* @author Yinq
* @date 2025-11-12
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpProjectReceiving.class, reverseConvertGenerate = false)
public class ErpProjectReceivingBo extends BaseEntity {
/**
* ID
*/
private Long receivingId;
/**
*
*/
private String projectCode;
/**
*
*/
private String projectName;
/**
* ID
*/
private Long projectId;
/**
*
*/
private Long managerId;
/**
*
*/
private Date arrivalDate;
/**
*
*/
private String ossId;
/**
* receiving_code
*/
private String receivingCode;
/**
*
*/
private Long chargeId;
/**
*
*/
private Long deputyId;
/**
*
*/
private String remark;
/**
*
*/
private String flowCode;
/**
*
*/
private String handler;
/**
*
*/
private Map<String, Object> variables;
/**
*
*/
private RemoteFlowInstanceBizExt bizExt;
/**
* {'entity': {}}
*/
public Map<String, Object> 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;
}
}

@ -0,0 +1,124 @@
package org.dromara.oa.erp.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.dromara.oa.erp.domain.ErpProjectAcceptance;
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_acceptance
*
* @author Yinq
* @date 2025-11-12
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpProjectAcceptance.class)
public class ErpProjectAcceptanceVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "验收确认ID")
private Long acceptanceId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "项目号")
private String projectCode;
/**
*
*/
@ExcelProperty(value = "项目名称")
private String projectName;
/**
*
*/
@ExcelProperty(value = "验收确认编号")
private String acceptanceCode;
/**
*
*/
@ExcelProperty(value = "项目经理")
private Long managerId;
/**
*
*/
@ExcelProperty(value = "项目经理姓名")
private String projectManagerName;
/**
*
*/
@ExcelProperty(value = "验收日期")
private Date acceptanceDate;
/**
*
*/
@ExcelProperty(value = "验收单附件")
private String ossId;
/**
*
*/
@ExcelProperty(value = "部门负责人")
private Long chargeId;
/**
*
*/
@ExcelProperty(value = "分管副总")
private Long deputyId;
/**
*
*/
@ExcelProperty(value = "部门负责人姓名")
private String chargeName;
/**
*
*/
@ExcelProperty(value = "分管副总姓名")
private String deputyName;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
/**
*
*/
@ExcelProperty(value = "流程状态")
private String flowStatus;
}

@ -0,0 +1,124 @@
package org.dromara.oa.erp.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.dromara.oa.erp.domain.ErpProjectReceiving;
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_receiving
*
* @author Yinq
* @date 2025-11-12
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpProjectReceiving.class)
public class ErpProjectReceivingVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "收货确认ID")
private Long receivingId;
/**
*
*/
@ExcelProperty(value = "项目号")
private String projectCode;
/**
*
*/
@ExcelProperty(value = "项目名称")
private String projectName;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "项目经理")
private Long managerId;
/**
*
*/
@ExcelProperty(value = "到货日期")
private Date arrivalDate;
/**
*
*/
@ExcelProperty(value = "收货单附件")
private String ossId;
/**
*
*/
@ExcelProperty(value = "项目经理姓名")
private String projectManagerName;
/**
*
*/
@ExcelProperty(value = "部门负责人")
private Long chargeId;
/**
*
*/
@ExcelProperty(value = "分管副总")
private Long deputyId;
/**
*
*/
@ExcelProperty(value = "部门负责人姓名")
private String chargeName;
/**
*
*/
@ExcelProperty(value = "分管副总姓名")
private String deputyName;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
/**
*
*/
@ExcelProperty(value = "流程状态")
private String flowStatus;
/**
*
*/
@ExcelProperty(value = "收货确认编号")
private String receivingCode;
}

@ -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.ErpProjectAcceptance;
import org.dromara.oa.erp.domain.vo.ErpProjectAcceptanceVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.common.mybatis.annotation.DataPermission;
import org.dromara.common.mybatis.annotation.DataColumn;
/**
* Mapper
*
* @author Yinq
* @date 2025-11-12
*/
public interface ErpProjectAcceptanceMapper extends BaseMapperPlus<ErpProjectAcceptance, ErpProjectAcceptanceVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
public Page<ErpProjectAcceptanceVo> selectCustomErpProjectAcceptanceVoList(@Param("page") Page<ErpProjectAcceptanceVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpProjectAcceptance> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
public List<ErpProjectAcceptanceVo> selectCustomErpProjectAcceptanceVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpProjectAcceptance> queryWrapper);
/**
* ID
*
* @param acceptanceId ID
* @return
*/
ErpProjectAcceptanceVo selectCustomErpProjectAcceptanceVoById(@Param("acceptanceId") Long acceptanceId);
/**
* ID
*
* @param ids ID
* @return
*/
List<ErpProjectAcceptanceVo> selectCustomErpProjectAcceptanceVoByIds(@Param("ids") Collection<Long> ids);
/**
*
*
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
Long countCustomErpProjectAcceptance(@Param(Constants.WRAPPER) Wrapper<ErpProjectAcceptance> queryWrapper);
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
Page<ErpProjectAcceptanceVo> selectCustomErpProjectAcceptanceVoPage(@Param("page") Page<ErpProjectAcceptanceVo> page, @Param(Constants.WRAPPER) Wrapper<ErpProjectAcceptance> queryWrapper);
/**
*
*
* @param list
* @return
*/
int batchInsertErpProjectAcceptance(@Param("list") List<ErpProjectAcceptance> list);
/**
*
*
* @param list
* @return
*/
int batchUpdateErpProjectAcceptance(@Param("list") List<ErpProjectAcceptance> list);
/**
*
*
* @param queryWrapper
* @return
*/
int deleteCustomErpProjectAcceptance(@Param(Constants.WRAPPER) Wrapper<ErpProjectAcceptance> queryWrapper);
/**
* ID
*
* @param ids ID
* @return
*/
int deleteCustomErpProjectAcceptanceByIds(@Param("ids") Collection<Long> ids);
/**
*
*
* @param queryWrapper
* @return
*/
Boolean existsErpProjectAcceptance(@Param(Constants.WRAPPER) Wrapper<ErpProjectAcceptance> queryWrapper);
}

@ -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.ErpProjectReceiving;
import org.dromara.oa.erp.domain.vo.ErpProjectReceivingVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.common.mybatis.annotation.DataPermission;
import org.dromara.common.mybatis.annotation.DataColumn;
/**
* Mapper
*
* @author Yinq
* @date 2025-11-12
*/
public interface ErpProjectReceivingMapper extends BaseMapperPlus<ErpProjectReceiving, ErpProjectReceivingVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
public Page<ErpProjectReceivingVo> selectCustomErpProjectReceivingVoList(@Param("page") Page<ErpProjectReceivingVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpProjectReceiving> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
public List<ErpProjectReceivingVo> selectCustomErpProjectReceivingVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpProjectReceiving> queryWrapper);
/**
* ID
*
* @param receivingId ID
* @return
*/
ErpProjectReceivingVo selectCustomErpProjectReceivingVoById(@Param("receivingId") Long receivingId);
/**
* ID
*
* @param ids ID
* @return
*/
List<ErpProjectReceivingVo> selectCustomErpProjectReceivingVoByIds(@Param("ids") Collection<Long> ids);
/**
*
*
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
Long countCustomErpProjectReceiving(@Param(Constants.WRAPPER) Wrapper<ErpProjectReceiving> queryWrapper);
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
Page<ErpProjectReceivingVo> selectCustomErpProjectReceivingVoPage(@Param("page") Page<ErpProjectReceivingVo> page, @Param(Constants.WRAPPER) Wrapper<ErpProjectReceiving> queryWrapper);
/**
*
*
* @param list
* @return
*/
int batchInsertErpProjectReceiving(@Param("list") List<ErpProjectReceiving> list);
/**
*
*
* @param list
* @return
*/
int batchUpdateErpProjectReceiving(@Param("list") List<ErpProjectReceiving> list);
/**
*
*
* @param queryWrapper
* @return
*/
int deleteCustomErpProjectReceiving(@Param(Constants.WRAPPER) Wrapper<ErpProjectReceiving> queryWrapper);
/**
* ID
*
* @param ids ID
* @return
*/
int deleteCustomErpProjectReceivingByIds(@Param("ids") Collection<Long> ids);
/**
*
*
* @param queryWrapper
* @return
*/
Boolean existsErpProjectReceiving(@Param(Constants.WRAPPER) Wrapper<ErpProjectReceiving> queryWrapper);
}

@ -0,0 +1,85 @@
package org.dromara.oa.erp.service;
import org.dromara.oa.erp.domain.ErpProjectAcceptance;
import org.dromara.oa.erp.domain.vo.ErpProjectAcceptanceVo;
import org.dromara.oa.erp.domain.bo.ErpProjectAcceptanceBo;
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-12
*/
public interface IErpProjectAcceptanceService {
/**
*
*
* @param acceptanceId
* @return
*/
ErpProjectAcceptanceVo queryById(Long acceptanceId);
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
TableDataInfo<ErpProjectAcceptanceVo> queryPageList(ErpProjectAcceptanceBo bo, PageQuery pageQuery);
/**
*
*
* @param bo
* @return
*/
List<ErpProjectAcceptanceVo> queryList(ErpProjectAcceptanceBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean insertByBo(ErpProjectAcceptanceBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean updateByBo(ErpProjectAcceptanceBo bo);
/**
*
*
* @param ids
* @param isValid
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* ID
*
* @param projectId ID
* @return
*/
ErpProjectAcceptanceVo prepareByProjectId(Long projectId);
/**
*
*
* @param bo
* @return
*/
ErpProjectAcceptanceVo submitAndFlowStart(ErpProjectAcceptanceBo bo);
}

@ -0,0 +1,85 @@
package org.dromara.oa.erp.service;
import org.dromara.oa.erp.domain.ErpProjectReceiving;
import org.dromara.oa.erp.domain.vo.ErpProjectReceivingVo;
import org.dromara.oa.erp.domain.bo.ErpProjectReceivingBo;
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-12
*/
public interface IErpProjectReceivingService {
/**
*
*
* @param receivingId
* @return
*/
ErpProjectReceivingVo queryById(Long receivingId);
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
TableDataInfo<ErpProjectReceivingVo> queryPageList(ErpProjectReceivingBo bo, PageQuery pageQuery);
/**
*
*
* @param bo
* @return
*/
List<ErpProjectReceivingVo> queryList(ErpProjectReceivingBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean insertByBo(ErpProjectReceivingBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean updateByBo(ErpProjectReceivingBo bo);
/**
*
*
* @param ids
* @param isValid
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* ID
*
* @param projectId ID
* @return
*/
ErpProjectReceivingVo prepareByProjectId(Long projectId);
/**
*
*
* @param bo
* @return
*/
ErpProjectReceivingVo submitAndFlowStart(ErpProjectReceivingBo bo);
}

@ -0,0 +1,314 @@
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.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.workflow.api.RemoteWorkflowService;
import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt;
import org.dromara.workflow.api.domain.RemoteStartProcess;
import org.dromara.workflow.api.event.ProcessEvent;
import org.springframework.context.event.EventListener;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.dromara.oa.erp.domain.bo.ErpProjectAcceptanceBo;
import org.dromara.oa.erp.domain.vo.ErpProjectAcceptanceVo;
import org.dromara.oa.erp.domain.ErpProjectAcceptance;
import org.dromara.oa.erp.domain.ErpProjectInfo;
import org.dromara.oa.erp.domain.vo.ErpProjectInfoVo;
import org.dromara.oa.erp.mapper.ErpProjectAcceptanceMapper;
import org.dromara.oa.erp.mapper.ErpProjectInfoMapper;
import org.dromara.oa.erp.service.IErpProjectAcceptanceService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.Objects;
/**
* Service
*
* @author Yinq
* @date 2025-11-12
*/
@RequiredArgsConstructor
@Service
@Slf4j
public class ErpProjectAcceptanceServiceImpl implements IErpProjectAcceptanceService {
private final ErpProjectAcceptanceMapper baseMapper;
private final ErpProjectInfoMapper projectInfoMapper;
@DubboReference(timeout = 30000)
private RemoteWorkflowService remoteWorkflowService;
/**
*
*
* @param acceptanceId
* @return
*/
@Override
public ErpProjectAcceptanceVo queryById(Long acceptanceId){
return baseMapper.selectCustomErpProjectAcceptanceVoById(acceptanceId);
}
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
@Override
public TableDataInfo<ErpProjectAcceptanceVo> queryPageList(ErpProjectAcceptanceBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<ErpProjectAcceptance> lqw = buildQueryWrapper(bo);
Page<ErpProjectAcceptanceVo> result = baseMapper.selectCustomErpProjectAcceptanceVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
*
*
* @param bo
* @return
*/
@Override
public List<ErpProjectAcceptanceVo> queryList(ErpProjectAcceptanceBo bo) {
MPJLambdaWrapper<ErpProjectAcceptance> lqw = buildQueryWrapper(bo);
return baseMapper.selectCustomErpProjectAcceptanceVoList(lqw);
}
private MPJLambdaWrapper<ErpProjectAcceptance> buildQueryWrapper(ErpProjectAcceptanceBo bo) {
Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<ErpProjectAcceptance> lqw = JoinWrappers.lambda(ErpProjectAcceptance.class)
.selectAll(ErpProjectAcceptance.class)
.eq(ErpProjectAcceptance::getDelFlag, "0")
.eq(bo.getProjectId() != null, ErpProjectAcceptance::getProjectId, bo.getProjectId())
.eq(StringUtils.isNotBlank(bo.getProjectCode()), ErpProjectAcceptance::getProjectCode, bo.getProjectCode())
.like(StringUtils.isNotBlank(bo.getProjectName()), ErpProjectAcceptance::getProjectName, bo.getProjectName())
.eq(bo.getManagerId() != null, ErpProjectAcceptance::getManagerId, bo.getManagerId())
.eq(bo.getAcceptanceDate() != null, ErpProjectAcceptance::getAcceptanceDate, bo.getAcceptanceDate())
.eq(StringUtils.isNotBlank(bo.getOssId()), ErpProjectAcceptance::getOssId, bo.getOssId())
.eq(bo.getChargeId() != null, ErpProjectAcceptance::getChargeId, bo.getChargeId())
.eq(bo.getDeputyId() != null, ErpProjectAcceptance::getDeputyId, bo.getDeputyId());
if (params != null) {
String beginTime = Convert.toStr(params.get("beginTime"));
String endTime = Convert.toStr(params.get("endTime"));
lqw.ge(StringUtils.isNotBlank(beginTime), ErpProjectAcceptance::getAcceptanceDate, beginTime)
.le(StringUtils.isNotBlank(endTime), ErpProjectAcceptance::getAcceptanceDate, endTime);
}
return lqw;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean insertByBo(ErpProjectAcceptanceBo bo) {
// 权限校验:只有项目经理才能提交
validateProjectManager(bo.getManagerId());
ErpProjectAcceptance add = MapstructUtils.convert(bo, ErpProjectAcceptance.class);
validEntityBeforeSave(add);
// 默认业务状态:暂存
if (StringUtils.isBlank(add.getAcceptanceStatus())) {
add.setAcceptanceStatus(OAStatusEnum.DRAFT.getStatus());
}
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setAcceptanceId(add.getAcceptanceId());
}
return flag;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean updateByBo(ErpProjectAcceptanceBo bo) {
// 权限校验:只有项目经理才能修改
ErpProjectAcceptance existing = baseMapper.selectById(bo.getAcceptanceId());
if (existing == null) {
throw new ServiceException("项目验收确认不存在");
}
validateProjectManager(existing.getManagerId());
ErpProjectAcceptance update = MapstructUtils.convert(bo, ErpProjectAcceptance.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
*
*/
private void validEntityBeforeSave(ErpProjectAcceptance entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* /
*
* @param managerId ID
*/
private void validateProjectManager(Long managerId) {
// 超级管理员跳过校验
if (LoginHelper.isSuperAdmin()) {
return;
}
// 普通用户判断当前用户ID是否等于项目经理ID
Long currentUserId = LoginHelper.getUserId();
if (!Objects.equals(currentUserId, managerId)) {
throw new ServiceException("只有项目经理才能提交或修改项目验收确认");
}
}
/**
*
*
* @param ids
* @param isValid
* @return
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
/**
* ID
*
* @param projectId ID
* @return
*/
@Override
public ErpProjectAcceptanceVo prepareByProjectId(Long projectId) {
if (projectId == null) {
throw new ServiceException("项目ID不能为空");
}
// 查询项目信息
ErpProjectInfoVo projectInfo = projectInfoMapper.selectVoById(projectId);
if (projectInfo == null) {
throw new ServiceException("项目信息不存在");
}
// 构造验收信息
ErpProjectAcceptanceVo vo = new ErpProjectAcceptanceVo();
vo.setProjectId(projectId);
vo.setProjectCode(projectInfo.getProjectCode());
vo.setProjectName(projectInfo.getProjectName());
vo.setManagerId(projectInfo.getManagerId());
vo.setProjectManagerName(projectInfo.getManagerName());
vo.setChargeId(projectInfo.getChargeId());
vo.setChargeName(projectInfo.getChargeName());
vo.setDeputyId(projectInfo.getDeputyId());
vo.setDeputyName(projectInfo.getDeputyName());
return vo;
}
/**
*
*
* @param bo
* @return
*/
@Override
@GlobalTransactional(rollbackFor = Exception.class)
public ErpProjectAcceptanceVo submitAndFlowStart(ErpProjectAcceptanceBo bo) {
// 权限校验:只有项目经理才能提交
validateProjectManager(bo.getManagerId());
ErpProjectAcceptance add = MapstructUtils.convert(bo, ErpProjectAcceptance.class);
validEntityBeforeSave(add);
// 保存或更新
if (StringUtils.isNull(bo.getAcceptanceId())) {
this.insertByBo(bo);
} else {
this.updateByBo(bo);
}
// 发起流程(空值保护)
if (bo.getVariables() == null) {
bo.setVariables(new java.util.HashMap<>());
}
bo.getVariables().put("ignore", true);
RemoteStartProcess startProcess = new RemoteStartProcess();
startProcess.setBusinessId(bo.getAcceptanceId().toString());
startProcess.setFlowCode(bo.getFlowCode());
startProcess.setVariables(bo.getVariables());
if (bo.getBizExt() == null) {
bo.setBizExt(new RemoteFlowInstanceBizExt());
}
if (StringUtils.isNotEmpty(bo.getAcceptanceCode())) {
bo.getBizExt().setBusinessCode(bo.getAcceptanceCode());
}
startProcess.setBizExt(bo.getBizExt());
bo.getBizExt().setBusinessId(startProcess.getBusinessId());
boolean flagOne = remoteWorkflowService.startCompleteTask(startProcess);
if (!flagOne) {
throw new ServiceException("流程发起异常");
}
return MapstructUtils.convert(add, ErpProjectAcceptanceVo.class);
}
/**
* (: 稿退)
*
* @param processEvent
*/
@EventListener(condition = "#processEvent.flowCode =='OAPA'")
public void processHandler(ProcessEvent processEvent) {
TenantHelper.dynamic(processEvent.getTenantId(), () -> {
log.info("项目验收流程执行:{}", processEvent.toString());
ErpProjectAcceptance acceptance = baseMapper.selectById(Convert.toLong(processEvent.getBusinessId()));
if (acceptance != null) {
// 更新流程状态
acceptance.setFlowStatus(processEvent.getStatus());
Map<String, Object> params = processEvent.getParams();
if (MapUtil.isNotEmpty(params)) {
// 办理人
String handler = Convert.toStr(params.get("handler"));
}
// 根据流程状态更新业务状态
if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())) {
acceptance.setAcceptanceStatus(OAStatusEnum.COMPLETED.getStatus());
log.info("项目验收确认完成: acceptanceId={}", acceptance.getAcceptanceId());
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.INVALID.getStatus())
|| Objects.equals(processEvent.getStatus(), BusinessStatusEnum.TERMINATION.getStatus())) {
acceptance.setAcceptanceStatus(OAStatusEnum.INVALID.getStatus());
}
baseMapper.updateById(acceptance);
}
});
}
}

@ -0,0 +1,310 @@
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.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.workflow.api.RemoteWorkflowService;
import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt;
import org.dromara.workflow.api.domain.RemoteStartProcess;
import org.dromara.workflow.api.event.ProcessEvent;
import org.springframework.context.event.EventListener;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.dromara.oa.erp.domain.bo.ErpProjectReceivingBo;
import org.dromara.oa.erp.domain.vo.ErpProjectReceivingVo;
import org.dromara.oa.erp.domain.ErpProjectReceiving;
import org.dromara.oa.erp.domain.ErpProjectInfo;
import org.dromara.oa.erp.domain.vo.ErpProjectInfoVo;
import org.dromara.oa.erp.mapper.ErpProjectReceivingMapper;
import org.dromara.oa.erp.mapper.ErpProjectInfoMapper;
import org.dromara.oa.erp.service.IErpProjectReceivingService;
import java.util.*;
/**
* Service
*
* @author Yinq
* @date 2025-11-12
*/
@RequiredArgsConstructor
@Service
@Slf4j
public class ErpProjectReceivingServiceImpl implements IErpProjectReceivingService {
private final ErpProjectReceivingMapper baseMapper;
private final ErpProjectInfoMapper projectInfoMapper;
@DubboReference(timeout = 30000)
private RemoteWorkflowService remoteWorkflowService;
/**
*
*
* @param receivingId
* @return
*/
@Override
public ErpProjectReceivingVo queryById(Long receivingId){
return baseMapper.selectCustomErpProjectReceivingVoById(receivingId);
}
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
@Override
public TableDataInfo<ErpProjectReceivingVo> queryPageList(ErpProjectReceivingBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<ErpProjectReceiving> lqw = buildQueryWrapper(bo);
Page<ErpProjectReceivingVo> result = baseMapper.selectCustomErpProjectReceivingVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
*
*
* @param bo
* @return
*/
@Override
public List<ErpProjectReceivingVo> queryList(ErpProjectReceivingBo bo) {
MPJLambdaWrapper<ErpProjectReceiving> lqw = buildQueryWrapper(bo);
return baseMapper.selectCustomErpProjectReceivingVoList(lqw);
}
private MPJLambdaWrapper<ErpProjectReceiving> buildQueryWrapper(ErpProjectReceivingBo bo) {
Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<ErpProjectReceiving> lqw = JoinWrappers.lambda(ErpProjectReceiving.class)
.selectAll(ErpProjectReceiving.class)
.eq(ErpProjectReceiving::getDelFlag, "0")
.eq(StringUtils.isNotBlank(bo.getProjectCode()), ErpProjectReceiving::getProjectCode, bo.getProjectCode())
.like(StringUtils.isNotBlank(bo.getProjectName()), ErpProjectReceiving::getProjectName, bo.getProjectName())
.eq(bo.getManagerId() != null, ErpProjectReceiving::getManagerId, bo.getManagerId())
.eq(bo.getArrivalDate() != null, ErpProjectReceiving::getArrivalDate, bo.getArrivalDate())
.eq(StringUtils.isNotBlank(bo.getOssId()), ErpProjectReceiving::getOssId, bo.getOssId())
.eq(bo.getChargeId() != null, ErpProjectReceiving::getChargeId, bo.getChargeId())
.eq(bo.getDeputyId() != null, ErpProjectReceiving::getDeputyId, bo.getDeputyId());
if (params != null) {
String beginTime = Convert.toStr(params.get("beginTime"));
String endTime = Convert.toStr(params.get("endTime"));
lqw.ge(StringUtils.isNotBlank(beginTime), ErpProjectReceiving::getArrivalDate, beginTime)
.le(StringUtils.isNotBlank(endTime), ErpProjectReceiving::getArrivalDate, endTime);
}
return lqw;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean insertByBo(ErpProjectReceivingBo bo) {
// 权限校验:只有项目经理才能提交
validateProjectManager(bo.getManagerId());
ErpProjectReceiving add = MapstructUtils.convert(bo, ErpProjectReceiving.class);
validEntityBeforeSave(add);
// 默认业务状态:暂存
if (StringUtils.isBlank(add.getReceivingStatus())) {
add.setReceivingStatus(OAStatusEnum.DRAFT.getStatus());
}
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setReceivingId(add.getReceivingId());
}
return flag;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean updateByBo(ErpProjectReceivingBo bo) {
// 权限校验:只有项目经理才能修改
ErpProjectReceiving existing = baseMapper.selectById(bo.getReceivingId());
if (existing == null) {
throw new ServiceException("项目收货确认不存在");
}
validateProjectManager(existing.getManagerId());
ErpProjectReceiving update = MapstructUtils.convert(bo, ErpProjectReceiving.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
*
*/
private void validEntityBeforeSave(ErpProjectReceiving entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* /
*
* @param managerId ID
*/
private void validateProjectManager(Long managerId) {
// 超级管理员跳过校验
if (LoginHelper.isSuperAdmin()) {
return;
}
// 普通用户判断当前用户ID是否等于项目经理ID
Long currentUserId = LoginHelper.getUserId();
if (!Objects.equals(currentUserId, managerId)) {
throw new ServiceException("只有项目经理才能提交或修改项目收货确认");
}
}
/**
*
*
* @param ids
* @param isValid
* @return
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
/**
* ID
*
* @param projectId ID
* @return
*/
@Override
public ErpProjectReceivingVo prepareByProjectId(Long projectId) {
if (projectId == null) {
throw new ServiceException("项目ID不能为空");
}
// 查询项目信息
ErpProjectInfoVo projectInfo = projectInfoMapper.selectVoById(projectId);
if (projectInfo == null) {
throw new ServiceException("项目信息不存在");
}
// 构造收货信息
ErpProjectReceivingVo vo = new ErpProjectReceivingVo();
vo.setProjectId(projectInfo.getProjectId());
vo.setProjectCode(projectInfo.getProjectCode());
vo.setProjectName(projectInfo.getProjectName());
vo.setManagerId(projectInfo.getManagerId());
vo.setProjectManagerName(projectInfo.getManagerName());
vo.setChargeId(projectInfo.getChargeId());
vo.setChargeName(projectInfo.getChargeName());
vo.setDeputyId(projectInfo.getDeputyId());
vo.setDeputyName(projectInfo.getDeputyName());
return vo;
}
/**
*
*
* @param bo
* @return
*/
@Override
@GlobalTransactional(rollbackFor = Exception.class)
public ErpProjectReceivingVo submitAndFlowStart(ErpProjectReceivingBo bo) {
// 权限校验:只有项目经理才能提交
validateProjectManager(bo.getManagerId());
ErpProjectReceiving add = MapstructUtils.convert(bo, ErpProjectReceiving.class);
validEntityBeforeSave(add);
// 保存或更新
if (StringUtils.isNull(bo.getReceivingId())) {
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.getReceivingId().toString());
startProcess.setFlowCode(bo.getFlowCode());
startProcess.setVariables(bo.getVariables());
if (bo.getBizExt() == null) {
bo.setBizExt(new RemoteFlowInstanceBizExt());
}
if (StringUtils.isNotEmpty(bo.getReceivingCode())) {
bo.getBizExt().setBusinessCode(bo.getReceivingCode());
}
startProcess.setBizExt(bo.getBizExt());
bo.getBizExt().setBusinessId(startProcess.getBusinessId());
boolean flagOne = remoteWorkflowService.startCompleteTask(startProcess);
if (!flagOne) {
throw new ServiceException("流程发起异常");
}
return MapstructUtils.convert(add, ErpProjectReceivingVo.class);
}
/**
* (: 稿退)
*
* @param processEvent
*/
@EventListener(condition = "#processEvent.flowCode =='OAPR'")
public void processHandler(ProcessEvent processEvent) {
TenantHelper.dynamic(processEvent.getTenantId(), () -> {
log.info("项目收货流程执行:{}", processEvent.toString());
ErpProjectReceiving receiving = baseMapper.selectById(Convert.toLong(processEvent.getBusinessId()));
if (receiving != null) {
// 更新流程状态
receiving.setFlowStatus(processEvent.getStatus());
Map<String, Object> params = processEvent.getParams();
if (MapUtil.isNotEmpty(params)) {
// 办理人
String handler = Convert.toStr(params.get("handler"));
}
// 根据流程状态更新业务状态
if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())) {
receiving.setReceivingStatus(OAStatusEnum.COMPLETED.getStatus());
log.info("项目收货确认完成: receivingId={}", receiving.getReceivingId());
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.INVALID.getStatus())
|| Objects.equals(processEvent.getStatus(), BusinessStatusEnum.TERMINATION.getStatus())) {
receiving.setReceivingStatus(OAStatusEnum.INVALID.getStatus());
}
baseMapper.updateById(receiving);
}
});
}
}

@ -0,0 +1,242 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpProjectAcceptanceMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpProjectAcceptanceVo" id="ErpProjectAcceptanceResult">
<id property="acceptanceId" column="acceptance_id"/>
<result property="projectId" column="project_id"/>
<result property="projectCode" column="project_code"/>
<result property="projectName" column="project_name"/>
<result property="managerId" column="manager_id"/>
<result property="projectManagerName" column="projectManagerName"/>
<result property="acceptanceDate" column="acceptance_date"/>
<result property="ossId" column="oss_id"/>
<result property="acceptanceCode" column="acceptance_code"/>
<result property="chargeId" column="charge_id"/>
<result property="chargeName" column="chargeName"/>
<result property="deputyId" column="deputy_id"/>
<result property="deputyName" column="deputyName"/>
<result property="remark" column="remark"/>
<result property="flowStatus" column="flow_status"/>
</resultMap>
<select id="selectCustomErpProjectAcceptanceVoList" resultMap="ErpProjectAcceptanceResult">
select t.acceptance_id, t.project_id, t.tenant_id, t.project_code, t.project_name, t.manager_id, u1.nick_name as projectManagerName,
t.acceptance_date, t.oss_id, t.acceptance_code,
t.charge_id, u3.nick_name as chargeName, t.deputy_id, u4.nick_name as deputyName, t.remark, t.flow_status, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_project_acceptance t
left join sys_user u1 on t.manager_id = u1.user_id
left join sys_user u3 on t.charge_id = u3.user_id
left join sys_user u4 on t.deputy_id = u4.user_id
${ew.getCustomSqlSegment}
</select>
<!-- 根据ID查询详情 -->
<select id="selectCustomErpProjectAcceptanceVoById" resultMap="ErpProjectAcceptanceResult">
select t.acceptance_id, t.project_id, t.tenant_id, t.project_code, t.project_name, t.manager_id, u1.nick_name as projectManagerName,
t.acceptance_date, t.oss_id, t.acceptance_code,
t.charge_id, u3.nick_name as chargeName, t.deputy_id, u4.nick_name as deputyName, t.remark, t.flow_status, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_project_acceptance t
left join sys_user u1 on t.manager_id = u1.user_id
left join sys_user u3 on t.charge_id = u3.user_id
left join sys_user u4 on t.deputy_id = u4.user_id
where t.acceptance_id = #{acceptanceId}
</select>
<!-- 批量查询 - 根据ID列表 -->
<select id="selectCustomErpProjectAcceptanceVoByIds" resultMap="ErpProjectAcceptanceResult">
select t.acceptance_id, t.tenant_id, t.project_id, t.project_code, t.project_name, t.manager_id, u1.nick_name as projectManagerName,
t.acceptance_date, t.oss_id, t.acceptance_code,
t.charge_id, u3.nick_name as chargeName, t.deputy_id, u4.nick_name as deputyName, t.remark, t.flow_status, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_project_acceptance t
left join sys_user u1 on t.manager_id = u1.user_id
left join sys_user u3 on t.charge_id = u3.user_id
left join sys_user u4 on t.deputy_id = u4.user_id
where t.acceptance_id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- 统计查询 -->
<select id="countCustomErpProjectAcceptance" resultType="java.lang.Long">
select count(1) from erp_project_acceptance t
${ew.getCustomSqlSegment}
</select>
<!-- 分页查询(带自定义条件) -->
<select id="selectCustomErpProjectAcceptanceVoPage" resultMap="ErpProjectAcceptanceResult">
select t.acceptance_id, t.tenant_id, t.project_id, t.project_code, t.project_name, t.manager_id, u1.nick_name as projectManagerName,
t.acceptance_date, t.oss_id, t.acceptance_code,
t.charge_id, u3.nick_name as chargeName, t.deputy_id, u4.nick_name as deputyName, t.remark, t.flow_status, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_project_acceptance t
left join sys_user u1 on t.manager_id = u1.user_id
left join sys_user u3 on t.charge_id = u3.user_id
left join sys_user u4 on t.deputy_id = u4.user_id
${ew.getCustomSqlSegment}
</select>
<!-- 批量插入 -->
<insert id="batchInsertErpProjectAcceptance">
insert into erp_project_acceptance(
tenant_id,
project_id,
project_code,
project_name,
manager_id,
acceptance_date,
oss_id,
acceptance_code,
charge_id,
deputy_id,
remark,
del_flag,
create_dept,
create_by,
create_time,
update_by,
update_time
)
values
<foreach collection="list" item="item" separator=",">
(
#{item.tenantId},
#{item.projectId},
#{item.projectCode},
#{item.projectName},
#{item.managerId},
#{item.acceptanceDate},
#{item.ossId},
#{item.acceptanceCode},
#{item.chargeId},
#{item.deputyId},
#{item.remark},
#{item.delFlag},
#{item.createDept},
#{item.createBy},
#{item.createTime},
#{item.updateBy},
#{item.updateTime}
)
</foreach>
</insert>
<!-- 批量更新 -->
<update id="batchUpdateErpProjectAcceptance">
<foreach collection="list" item="item" separator=";">
update erp_project_acceptance
<set>
<if test="item.tenantId != null and item.tenantId != ''">
tenant_id = #{item.tenantId},
</if>
<if test="item.projectId != null">
project_id = #{item.projectId},
</if>
<if test="item.projectCode != null and item.projectCode != ''">
project_code = #{item.projectCode},
</if>
<if test="item.projectName != null and item.projectName != ''">
project_name = #{item.projectName},
</if>
<if test="item.managerId != null">
manager_id = #{item.managerId},
</if>
<if test="item.acceptanceDate != null">
acceptance_date = #{item.acceptanceDate},
</if>
<if test="item.ossId != null and item.ossId != ''">
oss_id = #{item.ossId},
</if>
<if test="item.acceptanceCode != null and item.acceptanceCode != ''">
acceptance_code = #{item.acceptanceCode},
</if>
<if test="item.chargeId != null">
charge_id = #{item.chargeId},
</if>
<if test="item.deputyId != null">
deputy_id = #{item.deputyId},
</if>
<if test="item.remark != null and item.remark != ''">
remark = #{item.remark},
</if>
<if test="item.delFlag != null and item.delFlag != ''">
del_flag = #{item.delFlag},
</if>
<if test="item.createDept != null">
create_dept = #{item.createDept},
</if>
<if test="item.createBy != null">
create_by = #{item.createBy},
</if>
<if test="item.createTime != null">
create_time = #{item.createTime},
</if>
<if test="item.updateBy != null">
update_by = #{item.updateBy},
</if>
<if test="item.updateTime != null">
update_time = #{item.updateTime}
</if>
</set>
where acceptance_id = #{item.acceptanceId}
</foreach>
</update>
<!-- 根据自定义条件删除 -->
<delete id="deleteCustomErpProjectAcceptance">
delete from erp_project_acceptance
${ew.getCustomSqlSegment}
</delete>
<!-- 根据ID列表批量删除 -->
<delete id="deleteCustomErpProjectAcceptanceByIds">
delete from erp_project_acceptance
where acceptance_id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<!-- 检查是否存在 -->
<select id="existsErpProjectAcceptance" resultType="java.lang.Boolean">
select count(1) > 0 from erp_project_acceptance t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,242 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpProjectReceivingMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpProjectReceivingVo" id="ErpProjectReceivingResult">
<id property="receivingId" column="receiving_id"/>
<result property="projectId" column="project_id"/>
<result property="projectCode" column="project_code"/>
<result property="projectName" column="project_name"/>
<result property="managerId" column="manager_id"/>
<result property="projectManagerName" column="projectManagerName"/>
<result property="arrivalDate" column="arrival_date"/>
<result property="ossId" column="oss_id"/>
<result property="receivingCode" column="receiving_code"/>
<result property="chargeId" column="charge_id"/>
<result property="chargeName" column="chargeName"/>
<result property="deputyId" column="deputy_id"/>
<result property="deputyName" column="deputyName"/>
<result property="remark" column="remark"/>
<result property="flowStatus" column="flow_status"/>
</resultMap>
<select id="selectCustomErpProjectReceivingVoList" resultMap="ErpProjectReceivingResult">
select t.receiving_id, t.tenant_id, t.project_id, t.project_code, t.project_name, t.manager_id, u1.nick_name as projectManagerName,
t.arrival_date, t.oss_id, t.receiving_code,
t.charge_id, u3.nick_name as chargeName, t.deputy_id, u4.nick_name as deputyName, t.remark, t.flow_status, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_project_receiving t
left join sys_user u1 on t.manager_id = u1.user_id
left join sys_user u3 on t.charge_id = u3.user_id
left join sys_user u4 on t.deputy_id = u4.user_id
${ew.getCustomSqlSegment}
</select>
<!-- 根据ID查询详情 -->
<select id="selectCustomErpProjectReceivingVoById" resultMap="ErpProjectReceivingResult">
select t.receiving_id, t.tenant_id, t.project_id, t.project_code, t.project_name, t.manager_id, u1.nick_name as projectManagerName,
t.arrival_date, t.oss_id, t.receiving_code,
t.charge_id, u3.nick_name as chargeName, t.deputy_id, u4.nick_name as deputyName, t.remark, t.flow_status, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_project_receiving t
left join sys_user u1 on t.manager_id = u1.user_id
left join sys_user u3 on t.charge_id = u3.user_id
left join sys_user u4 on t.deputy_id = u4.user_id
where t.receiving_id = #{receivingId}
</select>
<!-- 批量查询 - 根据ID列表 -->
<select id="selectCustomErpProjectReceivingVoByIds" resultMap="ErpProjectReceivingResult">
select t.receiving_id, t.tenant_id, t.project_id, t.project_code, t.project_name, t.manager_id, u1.nick_name as projectManagerName,
t.arrival_date, t.oss_id, t.receiving_code,
t.charge_id, u3.nick_name as chargeName, t.deputy_id, u4.nick_name as deputyName, t.remark, t.flow_status, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_project_receiving t
left join sys_user u1 on t.manager_id = u1.user_id
left join sys_user u3 on t.charge_id = u3.user_id
left join sys_user u4 on t.deputy_id = u4.user_id
where t.receiving_id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- 统计查询 -->
<select id="countCustomErpProjectReceiving" resultType="java.lang.Long">
select count(1) from erp_project_receiving t
${ew.getCustomSqlSegment}
</select>
<!-- 分页查询(带自定义条件) -->
<select id="selectCustomErpProjectReceivingVoPage" resultMap="ErpProjectReceivingResult">
select t.receiving_id, t.tenant_id, t.project_id, t.project_code, t.project_name, t.manager_id, u1.nick_name as projectManagerName,
t.arrival_date, t.oss_id, t.receiving_code,
t.charge_id, u3.nick_name as chargeName, t.deputy_id, u4.nick_name as deputyName, t.remark, t.receiving_status, t.flow_status, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_project_receiving t
left join sys_user u1 on t.manager_id = u1.user_id
left join sys_user u3 on t.charge_id = u3.user_id
left join sys_user u4 on t.deputy_id = u4.user_id
${ew.getCustomSqlSegment}
</select>
<!-- 批量插入 -->
<insert id="batchInsertErpProjectReceiving">
insert into erp_project_receiving(
tenant_id,
project_id,
project_code,
project_name,
manager_id,
arrival_date,
oss_id,
receiving_code,
charge_id,
deputy_id,
remark,
del_flag,
create_dept,
create_by,
create_time,
update_by,
update_time
)
values
<foreach collection="list" item="item" separator=",">
(
#{item.tenantId},
#{item.projectId},
#{item.projectCode},
#{item.projectName},
#{item.managerId},
#{item.arrivalDate},
#{item.ossId},
#{item.receivingCode},
#{item.chargeId},
#{item.deputyId},
#{item.remark},
#{item.delFlag},
#{item.createDept},
#{item.createBy},
#{item.createTime},
#{item.updateBy},
#{item.updateTime}
)
</foreach>
</insert>
<!-- 批量更新 -->
<update id="batchUpdateErpProjectReceiving">
<foreach collection="list" item="item" separator=";">
update erp_project_receiving
<set>
<if test="item.tenantId != null and item.tenantId != ''">
tenant_id = #{item.tenantId},
</if>
<if test="item.projectId != null">
project_id = #{item.projectId},
</if>
<if test="item.projectCode != null and item.projectCode != ''">
project_code = #{item.projectCode},
</if>
<if test="item.projectName != null and item.projectName != ''">
project_name = #{item.projectName},
</if>
<if test="item.managerId != null">
manager_id = #{item.managerId},
</if>
<if test="item.arrivalDate != null">
arrival_date = #{item.arrivalDate},
</if>
<if test="item.ossId != null and item.ossId != ''">
oss_id = #{item.ossId},
</if>
<if test="item.receivingCode != null and item.receivingCode != ''">
receiving_code = #{item.receivingCode},
</if>
<if test="item.chargeId != null">
charge_id = #{item.chargeId},
</if>
<if test="item.deputyId != null">
deputy_id = #{item.deputyId},
</if>
<if test="item.remark != null and item.remark != ''">
remark = #{item.remark},
</if>
<if test="item.delFlag != null and item.delFlag != ''">
del_flag = #{item.delFlag},
</if>
<if test="item.createDept != null">
create_dept = #{item.createDept},
</if>
<if test="item.createBy != null">
create_by = #{item.createBy},
</if>
<if test="item.createTime != null">
create_time = #{item.createTime},
</if>
<if test="item.updateBy != null">
update_by = #{item.updateBy},
</if>
<if test="item.updateTime != null">
update_time = #{item.updateTime}
</if>
</set>
where receiving_id = #{item.receivingId}
</foreach>
</update>
<!-- 根据自定义条件删除 -->
<delete id="deleteCustomErpProjectReceiving">
delete from erp_project_receiving
${ew.getCustomSqlSegment}
</delete>
<!-- 根据ID列表批量删除 -->
<delete id="deleteCustomErpProjectReceivingByIds">
delete from erp_project_receiving
where receiving_id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<!-- 检查是否存在 -->
<select id="existsErpProjectReceiving" resultType="java.lang.Boolean">
select count(1) > 0 from erp_project_receiving t
${ew.getCustomSqlSegment}
</select>
</mapper>
Loading…
Cancel
Save