diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/controller/HrmAppropriationReqController.java b/fad-hrm/src/main/java/com/ruoyi/hrm/controller/HrmAppropriationReqController.java new file mode 100644 index 0000000..062f914 --- /dev/null +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/controller/HrmAppropriationReqController.java @@ -0,0 +1,65 @@ +package com.ruoyi.hrm.controller; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.hrm.domain.bo.HrmAppropriationReqBo; +import com.ruoyi.hrm.domain.vo.HrmAppropriationReqVo; +import com.ruoyi.hrm.service.IHrmAppropriationReqService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Arrays; +import java.util.List; + +/** + * 拨款申请 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/hrm/appropriation") +public class HrmAppropriationReqController extends BaseController { + + private final IHrmAppropriationReqService service; + + @GetMapping("/list") + public TableDataInfo list(HrmAppropriationReqBo bo, PageQuery pageQuery) { + return service.queryPageList(bo, pageQuery); + } + + @GetMapping("/{bizId}") + public R getInfo(@PathVariable @NotNull Long bizId) { + return R.ok(service.queryById(bizId)); + } + + @Log(title = "拨款单", businessType = BusinessType.INSERT) + @PostMapping + public R add(@Validated @RequestBody HrmAppropriationReqBo bo) { + return R.ok(service.insertByBo(bo)); + } + + @Log(title = "拨款单", businessType = BusinessType.UPDATE) + @PutMapping + public R edit(@Validated @RequestBody HrmAppropriationReqBo bo) { + return toAjax(service.updateByBo(bo)); + } + + @Log(title = "拨款单", businessType = BusinessType.DELETE) + @DeleteMapping("/{bizIds}") + public R remove(@PathVariable @NotEmpty Long[] bizIds) { + return toAjax(service.deleteWithValidByIds(Arrays.asList(bizIds), true)); + } + + @GetMapping("/all") + public R> all(HrmAppropriationReqBo bo) { + return R.ok(service.queryList(bo)); + } +} + diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/domain/HrmAppropriationReq.java b/fad-hrm/src/main/java/com/ruoyi/hrm/domain/HrmAppropriationReq.java new file mode 100644 index 0000000..3490795 --- /dev/null +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/domain/HrmAppropriationReq.java @@ -0,0 +1,64 @@ +package com.ruoyi.hrm.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; + +/** + * 拨款申请 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("hrm_appropriation_req") +public class HrmAppropriationReq extends BaseEntity { + + /** 业务ID */ + @TableId + private Long bizId; + + /** 申请人ID */ + private Long empId; + + /** 项目ID */ + private Long projectId; + + /** 拨款类型(预付款/进度款/尾款等) */ + private String appropriationType; + + /** 拨款金额 */ + private BigDecimal amount; + + /** 收款方名称 */ + private String payeeName; + + /** 收款银行 */ + private String bankName; + + /** 收款账号 */ + private String bankAccount; + + /** 拨款事由 */ + private String reason; + + /** 状态 draft/pending/approved/rejected/canceled */ + private String status; + + /** 申请附件oss_id列表(CSV) */ + private String accessoryApplyIds; + + /** 回执附件oss_id列表(CSV) */ + private String accessoryReceiptIds; + + /** 备注 */ + private String remark; + + /** 删除标识 0正常 2删除 */ + @TableLogic + private Integer delFlag; +} + diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/domain/bo/HrmAppropriationReqBo.java b/fad-hrm/src/main/java/com/ruoyi/hrm/domain/bo/HrmAppropriationReqBo.java new file mode 100644 index 0000000..5fcdbf6 --- /dev/null +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/domain/bo/HrmAppropriationReqBo.java @@ -0,0 +1,63 @@ +package com.ruoyi.hrm.domain.bo; + +import com.ruoyi.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + * 拨款申请 Bo + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class HrmAppropriationReqBo extends BaseEntity { + + /** 业务ID(编辑时必填) */ + private Long bizId; + + /** 申请人ID */ + @NotNull(message = "申请人不能为空") + private Long empId; + + /** 项目ID */ + private Long projectId; + + /** 拨款类型(预付款/进度款/尾款等) */ + private String appropriationType; + + /** 拨款金额 */ + @NotNull(message = "拨款金额不能为空") + private BigDecimal amount; + + /** 收款方名称 */ + private String payeeName; + + /** 收款银行 */ + private String bankName; + + /** 收款账号 */ + private String bankAccount; + + /** 拨款事由 */ + private String reason; + + /** 状态 draft/pending/approved/rejected/canceled */ + private String status; + + /** 无模板时,自选审批人 userId */ + private Long manualAssigneeUserId; + + /** 申请附件oss_id列表(CSV) */ + private String accessoryApplyIds; + + /** 回执附件oss_id列表(CSV) */ + private String accessoryReceiptIds; + + /** 备注 */ + private String remark; + + private Long tplId; +} + diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/domain/vo/HrmAppropriationReqVo.java b/fad-hrm/src/main/java/com/ruoyi/hrm/domain/vo/HrmAppropriationReqVo.java new file mode 100644 index 0000000..e41072f --- /dev/null +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/domain/vo/HrmAppropriationReqVo.java @@ -0,0 +1,112 @@ +package com.ruoyi.hrm.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 拨款申请 VO + */ +@Data +public class HrmAppropriationReqVo implements Serializable { + private static final long serialVersionUID = 1L; + + @Excel(name = "业务ID") + private Long bizId; + + @Excel(name = "申请人ID") + private Long empId; + + @Excel(name = "项目ID") + private Long projectId; + + @Excel(name = "项目代号") + private String projectCode; + + @Excel(name = "项目名称") + private String projectName; + + @Excel(name = "项目编号") + private String projectNum; + + @Excel(name = "项目类型") + private String projectType; + + @Excel(name = "项目地址") + private String address; + + @Excel(name = "项目总款") + private BigDecimal funds; + + @Excel(name = "项目负责人") + private String functionary; + + @Excel(name = "开始日期") + private Date beginTime; + + @Excel(name = "结束日期") + private Date finishTime; + + @Excel(name = "交货期") + private String delivery; + + @Excel(name = "质保期") + private String guarantee; + + @Excel(name = "优先级") + private String projectGrade; + + @Excel(name = "状态") + private String projectStatus; + + @Excel(name = "生产结项状态") + private Integer productStatus; + + @Excel(name = "项目代表色") + private String color; + + @Excel(name = "客户ID") + private Long customerId; + + @Excel(name = "拨款类型") + private String appropriationType; + + @Excel(name = "拨款金额") + private BigDecimal amount; + + @Excel(name = "收款方名称") + private String payeeName; + + @Excel(name = "收款银行") + private String bankName; + + @Excel(name = "收款账号") + private String bankAccount; + + @Excel(name = "拨款事由") + private String reason; + + @Excel(name = "状态") + private String status; + + @Excel(name = "申请附件") + private String accessoryApplyIds; + + @Excel(name = "回执附件") + private String accessoryReceiptIds; + + @Excel(name = "备注") + private String remark; + + private String createBy; + private Date createTime; + private String updateBy; + private Date updateTime; + + /** 流程实例ID */ + private Long instId; +} + diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/mapper/HrmAppropriationReqMapper.java b/fad-hrm/src/main/java/com/ruoyi/hrm/mapper/HrmAppropriationReqMapper.java new file mode 100644 index 0000000..aa94687 --- /dev/null +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/mapper/HrmAppropriationReqMapper.java @@ -0,0 +1,23 @@ +package com.ruoyi.hrm.mapper; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ruoyi.common.core.mapper.BaseMapperPlus; +import com.ruoyi.hrm.domain.HrmAppropriationReq; +import com.ruoyi.hrm.domain.bo.HrmAppropriationReqBo; +import com.ruoyi.hrm.domain.vo.HrmAppropriationReqVo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 拨款申请 Mapper + */ +public interface HrmAppropriationReqMapper extends BaseMapperPlus { + + HrmAppropriationReqVo selectVoWithProjectById(@Param("bizId") Long bizId); + + List selectVoWithProjectByPage(IPage page, @Param("bo") HrmAppropriationReqBo bo); + + List selectVoWithProjectList(@Param("bo") HrmAppropriationReqBo bo); +} + diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/service/IHrmAppropriationReqService.java b/fad-hrm/src/main/java/com/ruoyi/hrm/service/IHrmAppropriationReqService.java new file mode 100644 index 0000000..59c3a8c --- /dev/null +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/service/IHrmAppropriationReqService.java @@ -0,0 +1,31 @@ +package com.ruoyi.hrm.service; + +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.hrm.domain.bo.HrmAppropriationReqBo; +import com.ruoyi.hrm.domain.vo.HrmAppropriationReqVo; + +import java.util.Collection; +import java.util.List; + +/** + * 拨款申请 Service + */ +public interface IHrmAppropriationReqService { + + HrmAppropriationReqVo queryById(Long bizId); + + TableDataInfo queryPageList(HrmAppropriationReqBo bo, PageQuery pageQuery); + + List queryList(HrmAppropriationReqBo bo); + + List queryListWithProject(HrmAppropriationReqBo bo); + + HrmAppropriationReqVo insertByBo(HrmAppropriationReqBo bo); + + Boolean updateByBo(HrmAppropriationReqBo bo); + + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} + + diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/service/impl/HrmAppropriationReqServiceImpl.java b/fad-hrm/src/main/java/com/ruoyi/hrm/service/impl/HrmAppropriationReqServiceImpl.java new file mode 100644 index 0000000..b635e63 --- /dev/null +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/service/impl/HrmAppropriationReqServiceImpl.java @@ -0,0 +1,134 @@ +package com.ruoyi.hrm.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.helper.LoginHelper; +import com.ruoyi.hrm.domain.HrmAppropriationReq; +import com.ruoyi.hrm.domain.HrmFlowTemplate; +import com.ruoyi.hrm.domain.bo.HrmAppropriationReqBo; +import com.ruoyi.hrm.domain.bo.HrmFlowStartBo; +import com.ruoyi.hrm.domain.vo.HrmAppropriationReqVo; +import com.ruoyi.hrm.mapper.HrmAppropriationReqMapper; +import com.ruoyi.hrm.mapper.HrmFlowTemplateMapper; +import com.ruoyi.hrm.service.IHrmAppropriationReqService; +import com.ruoyi.hrm.service.IHrmFlowInstanceService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.List; + +/** + * 拨款申请 Service 实现 + */ +@RequiredArgsConstructor +@Service +public class HrmAppropriationReqServiceImpl implements IHrmAppropriationReqService { + + private final HrmAppropriationReqMapper baseMapper; + private final HrmFlowTemplateMapper flowTemplateMapper; + private final IHrmFlowInstanceService flowInstanceService; + + @Override + public HrmAppropriationReqVo queryById(Long bizId) { + return baseMapper.selectVoWithProjectById(bizId); + } + + @Override + public TableDataInfo queryPageList(HrmAppropriationReqBo bo, PageQuery pageQuery) { + Page result = pageQuery.build(); + result.setRecords(baseMapper.selectVoWithProjectByPage(result, bo)); + return TableDataInfo.build(result); + } + + @Override + public List queryList(HrmAppropriationReqBo bo) { + return baseMapper.selectVoWithProjectList(bo); + } + + @Override + public List queryListWithProject(HrmAppropriationReqBo bo) { + return baseMapper.selectVoWithProjectList(bo); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public HrmAppropriationReqVo insertByBo(HrmAppropriationReqBo bo) { + HrmAppropriationReq add = BeanUtil.toBean(bo, HrmAppropriationReq.class); + add.setStatus(defaultStatus(add.getStatus())); + boolean ok = baseMapper.insert(add) > 0; + + HrmAppropriationReqVo bean = BeanUtil.toBean(add, HrmAppropriationReqVo.class); + if (ok && "pending".equalsIgnoreCase(add.getStatus())) { + // 获取流程启动人ID + Long startUserId = LoginHelper.getUserId(); + + HrmFlowTemplate tpl = null; + // 1) 优先:前端明确选择了模板(tplId 不为空) + if (bo.getTplId() != null) { + tpl = flowTemplateMapper.selectOne(Wrappers.lambdaQuery() + .eq(HrmFlowTemplate::getTplId, bo.getTplId()) + .eq(HrmFlowTemplate::getBizType, "appropriation") + .eq(HrmFlowTemplate::getEnabled, 1) + .last("limit 1")); + } + + // 2) 手动审批:前端选择了手动审批人时,不允许兜底去找模板,否则会意外走到模板里的规则(例如 dept_leader) + boolean manualMode = bo.getTplId() == null && bo.getManualAssigneeUserId() != null; + + // 3) 兜底:只有在既没有 tplId、也没有手动审批人的情况下,才自动选择最新启用模板 + if (!manualMode && tpl == null) { + tpl = flowTemplateMapper.selectOne(Wrappers.lambdaQuery() + .eq(HrmFlowTemplate::getBizType, "appropriation") + .eq(HrmFlowTemplate::getEnabled, 1) + .orderByDesc(HrmFlowTemplate::getVersion) + .last("limit 1")); + } + HrmFlowStartBo start = new HrmFlowStartBo(); + if (tpl != null) { + start.setTplId(tpl.getTplId()); + } + start.setManualAssigneeUserId(bo.getManualAssigneeUserId()); + start.setBizType("appropriation"); + start.setBizId(add.getBizId()); + start.setStartUserId(startUserId); + Long instId = flowInstanceService.startInstance(start); + bean.setInstId(instId); + } + + return bean; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateByBo(HrmAppropriationReqBo bo) { + HrmAppropriationReq update = BeanUtil.toBean(bo, HrmAppropriationReq.class); + return baseMapper.updateById(update) > 0; + } + + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + return baseMapper.deleteBatchIds(ids) > 0; + } + + @SuppressWarnings("unused") + private LambdaQueryWrapper buildQueryWrapper(HrmAppropriationReqBo bo) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getBizId() != null, HrmAppropriationReq::getBizId, bo.getBizId()); + lqw.eq(bo.getEmpId() != null, HrmAppropriationReq::getEmpId, bo.getEmpId()); + lqw.eq(bo.getProjectId() != null, HrmAppropriationReq::getProjectId, bo.getProjectId()); + lqw.eq(bo.getAppropriationType() != null, HrmAppropriationReq::getAppropriationType, bo.getAppropriationType()); + lqw.eq(bo.getStatus() != null, HrmAppropriationReq::getStatus, bo.getStatus()); + return lqw; + } + + private String defaultStatus(String status) { + return status == null ? "draft" : status; + } +} + diff --git a/fad-hrm/src/main/resources/mapper/HrmAppropriationReqMapper.xml b/fad-hrm/src/main/resources/mapper/HrmAppropriationReqMapper.xml new file mode 100644 index 0000000..dd8c6d4 --- /dev/null +++ b/fad-hrm/src/main/resources/mapper/HrmAppropriationReqMapper.xml @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +