liyong
5 天以前 1c518e10a50050d383e714b581c94dea58ec4d67
fix(approve): 修复审批实例查询条件及流程控制问题

- 修复ApprovalInstanceMapper.xml中的business_type字段查询条件格式
- 将审批实例创建时间查询改为apply_time字段并调整日期范围查询逻辑
- 添加申请人姓名查询条件到审批实例查询
- 在审批实例更新前检查是否存在进行中的审批任务并抛出异常
- 在企业新闻服务中添加审批实例服务依赖注入
- 实现企业新闻编辑时重置审批流程功能
- 修复财务报销查询中的申请人代码查询条件
- 优化报销服务中的审批流程重置逻辑,仅在必要时删除审批实例
- 修复在职员工台账查询接口参数类型从实体类改为DTO
- 扩展员工台账查询支持部门ID筛选和合同开始时间筛选
- 在员工入职和更新时同步教育信息到员工基本信息
- 添加应急联系人信息查询到员工台账列表返回结果中
已修改11个文件
175 ■■■■ 文件已修改
src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/impl/FinReimbursementServiceImpl.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsServiceImpl.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/controller/StaffOnJobController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/dto/StaffOnJobDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/mapper/StaffOnJobMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/IStaffOnJobService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/approve/ApprovalInstanceMapper.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/approve/FinReimbursementMapper.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/staff/StaffOnJobMapper.xml 75 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java
@@ -25,6 +25,7 @@
import com.ruoyi.collaborativeApproval.pojo.EnterpriseNewsScopeDept;
import com.ruoyi.collaborativeApproval.pojo.EnterpriseNewsScopeUser;
import com.ruoyi.common.enums.*;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.security.LoginUser;
@@ -159,6 +160,16 @@
        if (approvalInstanceDto == null || approvalInstanceDto.getId() == null) {
            return false;
        }
        // 判断是否有正在进行的审批任务,有则不允许修改
        long pendingTaskCount = approvalTaskService.count(
                Wrappers.<ApprovalTask>lambdaQuery()
                        .eq(ApprovalTask::getInstanceId, approvalInstanceDto.getId())
                        .eq(ApprovalTask::getTaskStatus, "PENDING")
                        .eq(ApprovalTask::getDeleted, 0)
        );
        if (pendingTaskCount > 0) {
            throw new ServiceException("该审批单有正在进行的审批任务,不允许修改");
        }
        boolean updated = this.updateById(approvalInstanceDto);
        if (!updated) {
            return false;
src/main/java/com/ruoyi/approve/service/impl/FinReimbursementServiceImpl.java
@@ -199,7 +199,7 @@
            }
        }
        resetApprovalFlow(existing.getApprovalInstanceId(), reimbursementId);
        resetApprovalFlow(existing, reimbursementId);
        if (BILL_STATUS_IN_APPROVAL.equals(billStatus)) {
            reimbursement.setApprovalInstanceId(null);
            startApproval(reimbursement, finReimbursementDto);
@@ -498,11 +498,18 @@
        sysNoticeService.simpleNoticeByUser(title, message, approverIds, jumpPath);
    }
    private void resetApprovalFlow(Long approvalInstanceId, Long reimbursementId) {
        if (approvalInstanceId == null) {
    private void resetApprovalFlow(FinReimbursement existing, Long reimbursementId) {
        if (existing == null || existing.getApprovalInstanceId() == null) {
            return;
        }
        Long approvalInstanceId = existing.getApprovalInstanceId();
        if (!"REJECTED".equals(existing.getBillStatus())) {
        approvalInstanceService.delete(Collections.singletonList(approvalInstanceId));
        }
        clearApprovalBinding(reimbursementId);
    }
    private void clearApprovalBinding(Long reimbursementId) {
        int rows = finReimbursementMapper.update(
                null,
                Wrappers.<FinReimbursement>lambdaUpdate()
src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsServiceImpl.java
@@ -9,6 +9,7 @@
import com.ruoyi.approve.pojo.ApprovalInstance;
import com.ruoyi.approve.pojo.ApprovalTask;
import com.ruoyi.approve.pojo.ApprovalTemplate;
import com.ruoyi.approve.service.ApprovalInstanceService;
import com.ruoyi.approve.utils.ApproveProcessConfigNodeUtils;
import com.ruoyi.basic.enums.ApplicationTypeEnum;
import com.ruoyi.basic.enums.RecordTypeEnum;
@@ -72,6 +73,7 @@
    private final SysDeptMapper sysDeptMapper;
    private final SysUserDeptMapper sysUserDeptMapper;
    private final ApprovalInstanceMapper approvalInstanceMapper;
    private final ApprovalInstanceService approvalInstanceService;
    private final ApprovalTemplateMapper approvalTemplateMapper;
    private final ApproveProcessConfigNodeUtils approveProcessConfigNodeUtils;
    private final ISysNoticeService sysNoticeService;
@@ -160,6 +162,7 @@
        saveReadScopeRelations(enterpriseNews.getId(), readScope, deptIds, userIds);
        fileUtil.saveStorageAttachment(ApplicationTypeEnum.FILE, RecordTypeEnum.ENTERPRISE_NEWS, enterpriseNews.getId(), enterpriseNewsDto.getStorageBlobDTOs());
        if (STATUS_PENDING.equals(enterpriseNews.getStatus())) {
            resetEnterpriseNewsApprovalFlow(oldEnterpriseNews);
            startEnterpriseNewsApproval(enterpriseNews, enterpriseNewsDto);
        }
        return true;
@@ -318,6 +321,24 @@
                .eq(EnterpriseNewsScopeUser::getNewsId, newsId));
    }
    private void resetEnterpriseNewsApprovalFlow(EnterpriseNews oldEnterpriseNews) {
        if (oldEnterpriseNews == null || !STATUS_DRAFT.equals(oldEnterpriseNews.getStatus())) {
            return;
        }
        List<Long> approvalInstanceIds = approvalInstanceMapper.selectList(new LambdaQueryWrapper<ApprovalInstance>()
                        .eq(ApprovalInstance::getBusinessId, oldEnterpriseNews.getId())
                        .eq(ApprovalInstance::getBusinessType, TypeEnums.ENTERPRISE_NEWS_APPROVAL.getCode())
                        .eq(ApprovalInstance::getDeleted, (byte) 0))
                .stream()
                .map(ApprovalInstance::getId)
                .filter(id -> id != null && id > 0)
                .collect(Collectors.toList());
        if (StringUtils.isEmpty(approvalInstanceIds)) {
            return;
        }
        approvalInstanceService.delete(approvalInstanceIds);
    }
    private List<Long> distinctIds(List<Long> ids) {
        if (StringUtils.isEmpty(ids)) {
            return new ArrayList<>();
src/main/java/com/ruoyi/staff/controller/StaffOnJobController.java
@@ -39,7 +39,7 @@
     * @return
     */
    @GetMapping("/listPage")
    public AjaxResult staffOnJobListPage(Page page, StaffOnJob staffOnJob) {
    public AjaxResult staffOnJobListPage(Page page, StaffOnJobDto staffOnJob) {
        return AjaxResult.success(staffOnJobService.staffOnJobListPage(page, staffOnJob));
    }
src/main/java/com/ruoyi/staff/dto/StaffOnJobDto.java
@@ -25,4 +25,6 @@
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date contractEndTime;
    private Long sysDeptId;
}
src/main/java/com/ruoyi/staff/mapper/StaffOnJobMapper.java
@@ -14,7 +14,7 @@
@Mapper
public interface StaffOnJobMapper extends BaseMapper<StaffOnJob> {
    IPage<StaffOnJobDto> staffOnJobListPage(Page page, @Param("staffOnJob") StaffOnJob staffOnJob);
    IPage<StaffOnJobDto> staffOnJobListPage(Page page, @Param("staffOnJob") StaffOnJobDto staffOnJob);
    List<StaffOnJobDto> staffOnJobList(@Param("staffOnJob") StaffOnJob staffOnJob);
src/main/java/com/ruoyi/staff/service/IStaffOnJobService.java
@@ -14,7 +14,7 @@
public interface IStaffOnJobService extends IService<StaffOnJob> {
    IPage<StaffOnJobDto> staffOnJobListPage(Page page, StaffOnJob staffOnJob);
    IPage<StaffOnJobDto> staffOnJobListPage(Page page, StaffOnJobDto staffOnJob);
     StaffOnJobDto staffOnJobDetail(Long id);
src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
@@ -7,6 +7,7 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.dto.WordDateDto;
import com.ruoyi.project.system.domain.SysDept;
@@ -67,8 +68,9 @@
    //在职员工台账分页查询
    @Override
    public IPage<StaffOnJobDto> staffOnJobListPage(Page page, StaffOnJob staffOnJob) {
        return staffOnJobMapper.staffOnJobListPage(page,staffOnJob);
    public IPage<StaffOnJobDto> staffOnJobListPage(Page page, StaffOnJobDto staffOnJob) {
        IPage<StaffOnJobDto> staffOnJobDtoIPage = staffOnJobMapper.staffOnJobListPage(page, staffOnJob);
        return staffOnJobDtoIPage;
    }
    //新增入职
@@ -83,6 +85,7 @@
        }
        // 创建入职数据
        syncStudyInfoFromEducation(staffOnJobPrams);
        staffOnJobPrams.setContractExpireTime(staffOnJobPrams.getContractEndTime());
        staffOnJobPrams.setStaffState(1);
        staffOnJobMapper.insert(staffOnJobPrams);
@@ -141,6 +144,7 @@
        // 绑定子表数据
        bingingStaffOnJobExtra(id,staffOnJobParams);
        // 更新员工数据
        syncStudyInfoFromEducation(staffOnJobParams);
        staffOnJobParams.setContractExpireTime(staffOnJobParams.getContractEndTime());
        return staffOnJobMapper.updateById(staffOnJobParams);
    }
@@ -158,6 +162,7 @@
                    .forEach(staff -> staff.setStaffOnJobId(id)); // 赋值
            staffEducationService.saveBatch(staffOnJobPrams.getStaffEducationList());
        }
        // 新增工作经历
        if(CollectionUtils.isNotEmpty(staffOnJobPrams.getStaffWorkExperienceList())){
            staffOnJobPrams.getStaffWorkExperienceList().stream()
@@ -174,6 +179,28 @@
        }
    }
    private void syncStudyInfoFromEducation(StaffOnJob staffOnJobPrams) {
        if (staffOnJobPrams == null || CollectionUtils.isEmpty(staffOnJobPrams.getStaffEducationList())) {
            if (staffOnJobPrams != null) {
                staffOnJobPrams.setFirstStudy("/");
                staffOnJobPrams.setProfession("/");
            }
            return;
        }
        Optional<StaffEducation> matchedEducation = staffOnJobPrams.getStaffEducationList().stream()
                .filter(Objects::nonNull)
                .filter(education -> StringUtils.isNotEmpty(education.getMajor()))
                .findFirst();
        if (matchedEducation.isPresent()) {
            StaffEducation education = matchedEducation.get();
            staffOnJobPrams.setFirstStudy(education.getEducation());
            staffOnJobPrams.setProfession(education.getMajor());
            return;
        }
        staffOnJobPrams.setFirstStudy("/");
        staffOnJobPrams.setProfession("/");
    }
    /**
     * 通过员工id删除教育经历,工作经历,紧急联系人
src/main/resources/mapper/approve/ApprovalInstanceMapper.xml
@@ -41,12 +41,16 @@
            <if test="ew.businessType != null ">
                and ai. business_type = #{ew.businessType}
            </if>
            <if test="ew.createTime != null">
                and ai.create_time between to_date(#{ew.createTimeStart}) and to_date(#{ew.createTimeEnd})
            <if test="ew.createTimeStart != null and ew.createTimeEnd != null">
                and ai.apply_time &gt;= #{ew.createTimeStart}
                and ai.apply_time &lt;= #{ew.createTimeEnd}
            </if>
            <if test="ew.status != null">
                and ai.status = #{ew.status}
            </if>
            <if test="ew.applicantName != null and ew.applicantName !=''">
                and ai.applicant_name = #{ew.applicantName}
            </if>
        </where>
        order by ai.id desc
    </select>
src/main/resources/mapper/approve/FinReimbursementMapper.xml
@@ -48,8 +48,12 @@
            <if test="ew.applicantName != null and ew.applicantName != ''">
                and applicant_name like concat('%',#{ew.applicantName},'%')
            </if>
            <if test="ew.createTimeStart != null and ew.createTimeStart !=''">
                and create_time between to_date(#{ew.createTimeStart}) and to_date(#{ew.createTimeEnd})
            <if test="ew.applicantCode != null and ew.applicantCode != ''">
                and applicant_code like concat('%',#{ew.applicantCode},'%')
            </if>
            <if test="ew.createTimeStart != null and ew.createTimeStart !='' and ew.createTimeEnd != null and ew.createTimeEnd != ''">
                and create_time &gt;= #{ew.createTimeStart}
                and create_time &lt;= #{ew.createTimeEnd}
            </if>
        </where>
    </select>
src/main/resources/mapper/staff/StaffOnJobMapper.xml
@@ -3,29 +3,82 @@
<mapper namespace="com.ruoyi.staff.mapper.StaffOnJobMapper">
    <select id="staffOnJobListPage" resultType="com.ruoyi.staff.dto.StaffOnJobDto">
        SELECT
        staff_on_job.*,
        sp.post_name as postName,
        sd.dept_name as deptName,
        MIN(t1.contract_start_time) as contract_start_time,  -- 取最早合同开始时间
        MAX(t1.contract_end_time) as contract_end_time
        staff_on_job.id,
        staff_on_job.staff_state,
        staff_on_job.staff_no,
        staff_on_job.staff_name,
        staff_on_job.sex,
        staff_on_job.native_place,
        staff_on_job.sys_post_id,
        staff_on_job.sys_dept_id,
        staff_on_job.role_id,
        staff_on_job.adress,
        staff_on_job.first_study,
        staff_on_job.profession,
        staff_on_job.identity_card,
        staff_on_job.age,
        staff_on_job.phone,
        staff_on_job.contract_term,
        staff_on_job.contract_expire_time,
        staff_on_job.trial_end_date,
        staff_on_job.trial_start_date,
        staff_on_job.sign_date,
        staff_on_job.salary_select,
        staff_on_job.pro_salary,
        staff_on_job.date_select,
        staff_on_job.remark,
        staff_on_job.create_time,
        staff_on_job.create_user,
        staff_on_job.update_time,
        staff_on_job.update_user,
        staff_on_job.tenant_id,
        staff_on_job.alias,
        staff_on_job.birth_date,
        staff_on_job.nation,
        staff_on_job.marital_status,
        staff_on_job.pro_term,
        staff_on_job.positive_date,
        staff_on_job.basic_salary,
        staff_on_job.dept_id,
        sp.post_name AS post_name,
        sd.dept_name AS dept_name,
        MIN(t1.contract_start_time) AS contract_start_time,
        MAX(t1.contract_end_time) AS contract_end_time,
        (
        SELECT GROUP_CONCAT(sec.contact_name SEPARATOR ',')
        FROM staff_emergency_contact sec
        WHERE sec.staff_on_job_id = staff_on_job.id
        ) AS emergency_contact,
        (
        SELECT GROUP_CONCAT(sec.contact_phone SEPARATOR ',')
        FROM staff_emergency_contact sec
        WHERE sec.staff_on_job_id = staff_on_job.id
        ) AS emergency_contact_phone
        FROM staff_on_job
        LEFT JOIN sys_post sp ON sp.post_id = staff_on_job.sys_post_id
        LEFT JOIN sys_dept sd ON sd.dept_id = staff_on_job.sys_dept_id
        LEFT JOIN staff_contract as t1 ON t1.staff_on_job_id = staff_on_job.id
        WHERE 1=1
        LEFT JOIN staff_contract AS t1 ON t1.staff_on_job_id = staff_on_job.id
        <where>
        <if test="staffOnJob.staffState != null">
            AND staff_state = #{staffOnJob.staffState}
                AND staff_on_job.staff_state = #{staffOnJob.staffState}
        </if>
        <if test="staffOnJob.staffName != null and staffOnJob.staffName != '' ">
            AND staff_name LIKE CONCAT('%',#{staffOnJob.staffName},'%')
                AND staff_on_job.staff_name LIKE CONCAT('%',#{staffOnJob.staffName},'%')
        </if>
        <if test="staffOnJob.entryDateStart != null and staffOnJob.entryDateStart != '' ">
            AND contract_expire_time &gt;= DATE_FORMAT(#{staffOnJob.entryDateStart},'%Y-%m-%d')
                AND staff_on_job.contract_expire_time &gt;= DATE_FORMAT(#{staffOnJob.entryDateStart},'%Y-%m-%d')
        </if>
        <if test="staffOnJob.entryDateEnd != null and staffOnJob.entryDateEnd != '' ">
            AND contract_expire_time &lt;= DATE_FORMAT(#{staffOnJob.entryDateEnd},'%Y-%m-%d')
                AND staff_on_job.contract_expire_time &lt;= DATE_FORMAT(#{staffOnJob.entryDateEnd},'%Y-%m-%d')
        </if>
            <if test="staffOnJob.sysDeptId != null">
                AND staff_on_job.sys_dept_id = #{staffOnJob.sysDeptId}
            </if>
        </where>
        GROUP BY staff_on_job.id
        <if test="staffOnJob.contractStartTime != null">
            HAVING MIN(t1.contract_start_time) = #{staffOnJob.contractStartTime}
        </if>
    </select>
    <select id="staffOnJobList" resultType="com.ruoyi.staff.dto.StaffOnJobDto">
        SELECT