25c2c9961fa433203a9df936ad27583047261d60..06f622b85d24927adb499eb562b89f376e7dc752
2026-01-19 huminmin
删除StaffJoinLeaveRecord相关代码
06f622 对比 | 目录
2026-01-19 gongchunyi
fix: 修复同一公司下其他账号无法收到通知
03c38e 对比 | 目录
2026-01-19 zss
Merge branch 'jtwy' into dev_New
e02d6b 对比 | 目录
2026-01-19 liyong
feat(procurement): 添加质检关联入库
6ff4a7 对比 | 目录
2026-01-19 huminmin
员工台账-续签合同
57cd4d 对比 | 目录
2026-01-19 liyong
Merge remote-tracking branch 'origin/jtwy' into jtwy
b9d7eb 对比 | 目录
2026-01-19 liyong
feat(procurement): 添加产品型号筛选功能并优化待入库数量计算
405578 对比 | 目录
2026-01-19 yaowanxin
发货审批通过,直接生成出库记录
c11543 对比 | 目录
2026-01-19 huminmin
员工台账与部门关联
831fd1 对比 | 目录
2026-01-19 gongchunyi
fix: 部门ID取值错误
206255 对比 | 目录
2026-01-19 gongchunyi
fix: 修复删除最新来票记录后本次来票金额取值异常
ea857a 对比 | 目录
2026-01-19 maven
Merge remote-tracking branch 'origin/dev_New' into dev_New
2154a6 对比 | 目录
2026-01-19 maven
yys 销售台账导入接口
5fa5d9 对比 | 目录
2026-01-19 huminmin
Merge branch 'dev_New' of http://114.132.189.42:9002/r/product-inventory-ma...
2d6c0d 对比 | 目录
2026-01-19 huminmin
新增离职增删改查导出
e168d2 对比 | 目录
2026-01-19 yaowanxin
Merge remote-tracking branch 'origin/jtwy' into jtwy
2be90e 对比 | 目录
2026-01-19 yaowanxin
在同一记录中展示进行开票登记操作的未开票金额同步
cea844 对比 | 目录
2026-01-19 zss
Merge branch 'jtwy' into dev_New
d97290 对比 | 目录
2026-01-19 zss
Merge remote-tracking branch 'origin/jtwy' into jtwy
616832 对比 | 目录
2026-01-19 zss
调整工艺路线顺序
a68fa7 对比 | 目录
2026-01-19 gongchunyi
fix: 添加判空操作和检测指标维护的关联产品id参数传递错误
891d1c 对比 | 目录
2026-01-19 zss
Merge branch 'jtwy' into dev_New
2ca155 对比 | 目录
2026-01-19 zss
Merge remote-tracking branch 'origin/jtwy' into jtwy
2be292 对比 | 目录
2026-01-19 zss
生产订单绑定工艺路线bug
ccb573 对比 | 目录
2026-01-19 zss
生产订单绑定工艺路线bug
73d90d 对比 | 目录
2026-01-19 liyong
添加排序字段赋值,修改出库判断逻辑
a0b288 对比 | 目录
2026-01-19 zss
工艺路线的排序字段
7cf10a 对比 | 目录
2026-01-19 zss
工艺路线的排序字段
570d33 对比 | 目录
2026-01-19 gongchunyi
fix: 新增和更新时校验会议室时间占用冲突
e94151 对比 | 目录
2026-01-19 maven
yys 优化首页待办事项接口
f82cee 对比 | 目录
已添加7个文件
已修改39个文件
已删除8个文件
2059 ■■■■■ 文件已修改
doc/20260115_add_sys_post_id_to_staff_join_leave_record.sql 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260119-procurement_record_storage.sql 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/collaborativeApproval/controller/MeetingController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/collaborativeApproval/service/MeetingService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/StaffJoinLeaveRecordDimissionReason.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/StaffLeaveReason.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementAddDto.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementPageDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java 140 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/controller/QualityInspectController.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/service/IQualityInspectService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesLedgerImportDto.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/controller/PersonalAttendanceRecordsController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/controller/StaffJoinLeaveRecordController.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/controller/StaffLeaveController.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/controller/StaffOnJobController.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/dto/StaffJoinLeaveRecordDto.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/dto/StaffLeaveDto.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/dto/StaffOnJobDto.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/mapper/StaffJoinLeaveRecordMapper.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/mapper/StaffLeaveMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/pojo/StaffJoinLeaveRecord.java 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/pojo/StaffLeave.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/IStaffJoinLeaveRecordService.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/IStaffOnJobService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/StaffContractService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/StaffLeaveService.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/StaffJoinLeaveRecordServiceImpl.java 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/basic/ProductModelMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/staff/StaffJoinLeaveRecordMapper.xml 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/staff/StaffLeaveMapper.xml 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/staff/StaffOnJobMapper.xml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/system/SysUserMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260115_add_sys_post_id_to_staff_join_leave_record.sql
@@ -1,8 +1,6 @@
alter table staff_join_leave_record
alter table staff_on_job
    add sys_post_id bigint not null default 0 comment '岗位id';
alter table staff_join_leave_record
alter table staff_on_job
drop column post_job;
alter table staff_on_job
    add sys_post_id bigint not null default 0 comment '岗位id';
alter table staff_on_job
drop column post_job;
    add sys_dept_id bigint default 0 not null;
doc/20260119-procurement_record_storage.sql
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,2 @@
alter table procurement_record_storage
    add quality_inspect_id bigint null comment '质检id';
src/main/java/com/ruoyi/collaborativeApproval/controller/MeetingController.java
@@ -83,8 +83,7 @@
    @PostMapping("/saveMeetingApplication")
    public R saveMeetApplication(@RequestBody MeetApplication meetApplication) {
        meetingService.saveMeetApplication(meetApplication);
        return R.ok();
       return meetingService.saveMeetApplication(meetApplication);
    }
    @PostMapping("/applicationList")
src/main/java/com/ruoyi/collaborativeApproval/service/MeetingService.java
@@ -14,6 +14,7 @@
import com.ruoyi.collaborativeApproval.vo.SearchMeetingDraftVo;
import com.ruoyi.collaborativeApproval.vo.SearchMeetingRoomVo;
import com.ruoyi.collaborativeApproval.vo.SearchMeetingUseVo;
import com.ruoyi.framework.web.domain.R;
import java.util.List;
@@ -42,7 +43,7 @@
// ************申请会议************
    void saveMeetApplication(MeetApplication meetApplication);
    R<Void> saveMeetApplication(MeetApplication meetApplication);
// ************申请审批************
src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java
@@ -26,11 +26,12 @@
import com.ruoyi.collaborativeApproval.vo.SearchMeetingRoomVo;
import com.ruoyi.collaborativeApproval.vo.SearchMeetingUseVo;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.project.system.service.ISysNoticeService;
import com.ruoyi.staff.mapper.StaffJoinLeaveRecordMapper;
import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
import com.ruoyi.staff.mapper.StaffOnJobMapper;
import com.ruoyi.staff.pojo.StaffOnJob;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -47,11 +48,12 @@
    private final MeetDraftMapper meetDraftMapper;
    private final MeetApplicationMapper meetApplicationMapper;
    private final StaffJoinLeaveRecordMapper staffJoinLeaveRecordMapper;
    private final StaffOnJobMapper staffOnJobMapper;
    private final MeetingMinutesMapper meetingMinutesMapper;
    private final SysUserMapper userMapper;
    private final ISysNoticeService sysNoticeService;
    @Override
    public IPage<MeetingRoom> getMeetingRoomList(SearchMeetingRoomVo vo) {
@@ -125,42 +127,72 @@
    }
    @Override
    public void saveMeetApplication(MeetApplication meetApplication) {
    public R<Void> saveMeetApplication(MeetApplication meetApplication) {
        meetApplication.setApplicant(SecurityUtils.getUsername());
        //  æ—¶é—´å†²çªæ ¡éªŒ
        LambdaQueryWrapper<MeetApplication> meetApplicationLambdaQueryWrapper = Wrappers.<MeetApplication>lambdaQuery()
                .eq(MeetApplication::getRoomId, meetApplication.getRoomId())
                // å¦‚æžœid不为null则排除自己
                .ne(meetApplication.getId() != null, MeetApplication::getId, meetApplication.getId())
                // æ—¶é—´å†²çªåˆ¤æ–­
                .lt(MeetApplication::getStartTime, meetApplication.getEndTime())
                .gt(MeetApplication::getEndTime, meetApplication.getStartTime());
        Long count = meetApplicationMapper.selectCount(meetApplicationLambdaQueryWrapper);
        if (count > 0) {
            return R.fail("所选会议室在该时间段已有其他会议,请调整时间或更换会议室");
        }
        if (meetApplication.getId() != null) {
            // æ›´æ–°
            meetApplicationMapper.updateById(meetApplication);
        } else {
            // æ–°å¢ž
            meetApplicationMapper.insert(meetApplication);
        }
        if (ObjectUtils.isNotNull(meetApplication.getPublishStatus()) && meetApplication.getPublishStatus() == 1){
        /*会议发布的消息通知*/
        //参会人员id(人员台账和用户表通过人员编号和用户名称(登录账号)做匹配)
        if (Integer.valueOf(1).equals(meetApplication.getPublishStatus())) {
            MeetApplication application = meetApplicationMapper.selectById(meetApplication.getId());
            /*会议发布的消息通知*/
            //参会人员id(人员台账和用户表通过人员编号和用户名称(登录账号)做匹配)
            String cleanStr = application.getParticipants().trim()
            String cleanStr = application.getParticipants()
                    .replaceAll("^\\[|\\]$", "")
                    .trim();
            List<Long> ids = Arrays.stream(cleanStr.split(","))
            List<Long> userIds = Arrays.stream(cleanStr.split(","))
                    .map(String::trim)
                    .filter(s -> !s.isEmpty())
                    .map(s -> {
                        StaffJoinLeaveRecord staffJoinLeaveRecord = staffJoinLeaveRecordMapper.selectById(Long.valueOf(s));
                        List<SysUser> users = userMapper.selectList(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUserName,staffJoinLeaveRecord.getStaffNo()));
                        if (users.size() > 0){
                            return users.get(0).getUserId();
                        }else return null;
                    .map(Long::valueOf)
                    .map(staffId -> {
                        StaffOnJob record = staffOnJobMapper.selectById(staffId);
                        if (record == null) {
                            return null;
                        }
                        return userMapper.selectOne(
                                Wrappers.<SysUser>lambdaQuery()
                                        .eq(SysUser::getUserName, record.getStaffNo())
                        );
                    })
                    .filter(Objects::nonNull)
                    .map(SysUser::getUserId)
                    .collect(Collectors.toList());
            if (ids.size() > 0) {
                sysNoticeService.simpleNoticeByUser("会议通知",
            if (!userIds.isEmpty()) {
                sysNoticeService.simpleNoticeByUser(
                        "会议通知",
                        "会议主题:" + application.getTitle() + "\n" +
                                "会议时间:" + application.getStartTime() + "-" + application.getEndTime() + "\n" +
                                "发起人:" + application.getApplicant(),
                        ids,
                        userIds,
                        application.getTenantId(),
                        "");
                        ""
                );
            }
        }
        return R.ok();
    }
    @Override
src/main/java/com/ruoyi/common/enums/StaffJoinLeaveRecordDimissionReason.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/common/enums/StaffLeaveReason.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.ruoyi.common.enums;
import lombok.AllArgsConstructor;
/**
 * é™„件记录类型枚举
 *
 */
@AllArgsConstructor
public enum StaffLeaveReason {
    StaffLeaveReasonSalary("salary","薪资待遇"),
    StaffLeaveReasonCareerDevelopment("career_development","职业发展"),
    StaffLeaveReasonWorkEnvironment("work_environment","工作环境"),
    StaffLeaveReasonPersonalReason("personal_reason","个人原因"),
    StaffLeaveReasonOther("other","其他原因");
    private final String code;
    private final String info;
    public String getCode() {
        return code;
    }
    public String getInfo() {
        return info;
    }
}
src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
@@ -526,6 +526,176 @@
    }
    /**
     * æ‰©å±•:读取Excel中多个指定Sheet的数据
     * @param sheetNameList è¦è¯»å–çš„Sheet名称列表(null则读取所有Sheet)
     * @param is è¾“入流
     * @param titleNum æ ‡é¢˜å ç”¨è¡Œæ•°
     * @return Map<Sheet名称, å¯¹åº”Sheet的数据列表>
     */
    public Map<String, List<T>> importExcelMultiSheet(List<String> sheetNameList, InputStream is, int titleNum) {
        Map<String, List<T>> resultMap = new HashMap<>();
        try {
            this.type = Type.IMPORT;
            this.wb = WorkbookFactory.create(is);
            // 1. ç¡®å®šè¦è¯»å–çš„Sheet列表
            List<Sheet> sheetsToRead = new ArrayList<>();
            if (sheetNameList != null && !sheetNameList.isEmpty()) {
                // è¯»å–指定名称的Sheet
                for (String sheetName : sheetNameList) {
                    Sheet sheet = wb.getSheet(sheetName);
                    if (sheet != null) {
                        sheetsToRead.add(sheet);
                    } else {
                        log.warn("指定的Sheet名称不存在:{}", sheetName);
                    }
                }
            } else {
                // è¯»å–所有Sheet
                int sheetCount = wb.getNumberOfSheets();
                for (int i = 0; i < sheetCount; i++) {
                    sheetsToRead.add(wb.getSheetAt(i));
                }
            }
            // 2. éåŽ†æ¯ä¸ªSheet,复用原有导入逻辑
            for (Sheet sheet : sheetsToRead) {
                String sheetName = wb.getSheetName(wb.getSheetIndex(sheet));
                // å¤ç”¨åŽŸæœ‰æ ¸å¿ƒå¯¼å…¥é€»è¾‘ï¼ˆå…³é”®ï¼šå°†åŽŸæœ‰æ–¹æ³•æ‹†åˆ†ä¸ºå¯å¤ç”¨çš„å†…éƒ¨æ–¹æ³•ï¼‰
                List<T> sheetData = importExcelBySheet(sheet, titleNum);
                resultMap.put(sheetName, sheetData);
            }
        } catch (Exception e) {
            log.error("导入多Sheet Excel异常{}", e.getMessage());
            throw new UtilException(e.getMessage());
        } finally {
            IOUtils.closeQuietly(is);
        }
        return resultMap;
    }
    /**
     * å†…部复用方法:根据指定Sheet对象读取数据(提取原有importExcel的核心逻辑)
     */
    private List<T> importExcelBySheet(Sheet sheet, int titleNum) throws Exception {
        List<T> list = new ArrayList<T>();
        if (sheet == null) {
            return list;
        }
        boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook);
        Map<String, List<PictureData>> pictures = null;
        if (isXSSFWorkbook) {
            pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb);
        } else {
            pictures = getSheetPictures03((HSSFSheet) sheet, (HSSFWorkbook) wb);
        }
        int rows = sheet.getLastRowNum();
        if (rows > 0) {
            Map<String, Integer> cellMap = new HashMap<String, Integer>();
            Row heard = sheet.getRow(titleNum);
            for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) {
                Cell cell = heard.getCell(i);
                if (StringUtils.isNotNull(cell)) {
                    String value = this.getCellValue(heard, i).toString();
                    cellMap.put(value, i);
                } else {
                    cellMap.put(null, i);
                }
            }
            List<Object[]> fields = this.getFields();
            Map<Integer, Object[]> fieldsMap = new HashMap<Integer, Object[]>();
            for (Object[] objects : fields) {
                Excel attr = (Excel) objects[1];
                Integer column = cellMap.get(attr.name());
                if (column != null) {
                    fieldsMap.put(column, objects);
                }
            }
            for (int i = titleNum + 1; i <= rows; i++) {
                Row row = sheet.getRow(i);
                if (isRowEmpty(row)) {
                    continue;
                }
                T entity = null;
                for (Map.Entry<Integer, Object[]> entry : fieldsMap.entrySet()) {
                    Object val = this.getCellValue(row, entry.getKey());
                    entity = (entity == null ? clazz.newInstance() : entity);
                    Field field = (Field) entry.getValue()[0];
                    Excel attr = (Excel) entry.getValue()[1];
                    Class<?> fieldType = field.getType();
                    // ä»¥ä¸‹æ˜¯åŽŸæœ‰æ•°æ®ç±»åž‹è½¬æ¢ã€å­—å…¸è§£æžç­‰é€»è¾‘ï¼ˆå®Œå…¨å¤ç”¨ï¼‰
                    if (String.class == fieldType) {
                        String s = Convert.toStr(val);
                        if (s.matches("^\\d+\\.0$")) {
                            val = StringUtils.substringBefore(s, ".0");
                        } else {
                            String dateFormat = field.getAnnotation(Excel.class).dateFormat();
                            if (StringUtils.isNotEmpty(dateFormat)) {
                                val = parseDateToStr(dateFormat, val);
                            } else {
                                val = Convert.toStr(val);
                            }
                        }
                    } else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) {
                        val = Convert.toInt(val);
                    } else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) {
                        val = Convert.toLong(val);
                    } else if (Double.TYPE == fieldType || Double.class == fieldType) {
                        val = Convert.toDouble(val);
                    } else if (Float.TYPE == fieldType || Float.class == fieldType) {
                        val = Convert.toFloat(val);
                    } else if (BigDecimal.class == fieldType) {
                        val = Convert.toBigDecimal(val);
                    } else if (Date.class == fieldType) {
                        if (val instanceof String) {
                            val = DateUtils.parseDate(val);
                        } else if (val instanceof Double) {
                            val = DateUtil.getJavaDate((Double) val);
                        }
                    } else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) {
                        val = Convert.toBool(val, false);
                    }
                    if (StringUtils.isNotNull(fieldType)) {
                        String propertyName = field.getName();
                        if (StringUtils.isNotEmpty(attr.targetAttr())) {
                            propertyName = field.getName() + "." + attr.targetAttr();
                        }
                        if (StringUtils.isNotEmpty(attr.readConverterExp())) {
                            val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
                        } else if (StringUtils.isNotEmpty(attr.dictType())) {
                            if (!sysDictMap.containsKey(attr.dictType() + val)) {
                                String dictValue = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator());
                                sysDictMap.put(attr.dictType() + val, dictValue);
                            }
                            val = sysDictMap.get(attr.dictType() + val);
                        } else if (!attr.handler().equals(ExcelHandlerAdapter.class)) {
                            val = dataFormatHandlerAdapter(val, attr, null);
                        } else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures)) {
                            StringBuilder propertyString = new StringBuilder();
                            List<PictureData> images = pictures.get(row.getRowNum() + "_" + entry.getKey());
                            for (PictureData picture : images) {
                                byte[] data = picture.getData();
                                String fileName = FileUtils.writeImportBytes(data);
                                propertyString.append(fileName).append(SEPARATOR);
                            }
                            val = StringUtils.stripEnd(propertyString.toString(), SEPARATOR);
                        }
                        ReflectUtils.invokeSetter(entity, propertyName, val);
                    }
                }
                list.add(entity);
            }
        }
        return list;
    }
    /**
     * å¯¹list数据源将其里面的数据导入到excel表单
     * 
     * @param list å¯¼å‡ºæ•°æ®é›†åˆ
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -384,23 +384,23 @@
        if(CollectionUtils.isEmpty(approveProcesses)){
            approveProcesses = new ArrayList<>();
        }
        // æŸ¥è¯¢æœªé¢†ç”¨åŠ³ä¿è®°å½•
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        LaborIssue laborIssue1 = new LaborIssue();
        laborIssue1.setAdoptedDate(new Date());
        laborIssue1.setIssueDate(sdf.parse(sdf.format(new Date())));
        List<LaborIssue> laborIssues = lavorIssueMapper.list(laborIssue1);
        if(!CollectionUtils.isEmpty(laborIssues)){
            for (LaborIssue laborIssue : laborIssues) {
                ApproveProcess approveProcess = new ApproveProcess();
                approveProcess.setApproveId(laborIssue.getOrderNo());
                approveProcess.setApproveDeptName(sysDeptMapper.selectDeptById(loginUser.getTenantId()).getDeptName());
                approveProcess.setApproveTime(laborIssue.getIssueDate());
                approveProcess.setApproveReason(laborIssue.getDictTypeName() + "-" + laborIssue.getDictName() + "超时未领取");
                approveProcesses.add(approveProcess);
            }
        }
//        // æŸ¥è¯¢æœªé¢†ç”¨åŠ³ä¿è®°å½•
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//
//        LaborIssue laborIssue1 = new LaborIssue();
//        laborIssue1.setAdoptedDate(new Date());
//        laborIssue1.setIssueDate(sdf.parse(sdf.format(new Date())));
//        List<LaborIssue> laborIssues = lavorIssueMapper.list(laborIssue1);  //staff_join_leave_record表被删除
//        if(!CollectionUtils.isEmpty(laborIssues)){
//            for (LaborIssue laborIssue : laborIssues) {
//                ApproveProcess approveProcess = new ApproveProcess();
//                approveProcess.setApproveId(laborIssue.getOrderNo());
//                approveProcess.setApproveDeptName(sysDeptMapper.selectDeptById(loginUser.getTenantId()).getDeptName());
//                approveProcess.setApproveTime(laborIssue.getIssueDate());
//                approveProcess.setApproveReason(laborIssue.getDictTypeName() + "-" + laborIssue.getDictName() + "超时未领取");
//                approveProcesses.add(approveProcess);
//            }
//        }
        return approveProcesses;
    }
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementAddDto.java
@@ -22,5 +22,6 @@
    private String typeName;
    private Integer purchaseLedgerId;
    private Long qualityInspectId;
}
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementPageDto.java
@@ -192,4 +192,6 @@
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate endDate;
    private Long productModelId;
}
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java
@@ -100,4 +100,6 @@
     * äº§å“ID
     */
    private Long productModelId;
    private Long qualityInspectId;
}
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
@@ -781,7 +781,8 @@
                    .updateTime(LocalDateTime.now())
                    .updateUser(loginUser.getUserId())
                    .createBy(procurementDto.getNickName())
                    .productModelId(detail.getProductModelId());
                    .productModelId(detail.getProductModelId())
                    .qualityInspectId(ObjectUtils.isNotNull(procurementDto.getQualityInspectId())?procurementDto.getQualityInspectId():0L);
            this.save(procurementRecordBuilder.build());
            // å…¥åº“成功减掉采购数量
//            LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductLambdaQueryWrapper = new LambdaQueryWrapper<>();
@@ -896,6 +897,42 @@
    @Override
    public IPage<ProcurementPageDto> listPageByProductProduction(Page page, ProcurementPageDto procurementDto) {
        IPage<ProcurementPageDto> procurementPageDtoIPage = procurementRecordMapper.listPageByProductProduction(page, procurementDto);
        List<ProcurementPageDto> procurementPageDtos = procurementPageDtoIPage.getRecords();
        // è®¡ç®—待入库数量
        // æŸ¥è¯¢é‡‡è´­è®°å½•已入库数量
        List<Integer> collect = procurementPageDtos.stream().map(ProcurementPageDto::getId).collect(Collectors.toList());
        if(CollectionUtils.isEmpty( collect)){
            return procurementPageDtoIPage;
        }
        LambdaQueryWrapper<ProcurementRecordOut> procurementRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        procurementRecordLambdaQueryWrapper.in(ProcurementRecordOut::getProcurementRecordStorageId, collect)
                .eq(ProcurementRecordOut::getType, 4);
        List<ProcurementRecordOut> procurementRecords = procurementRecordOutMapper.selectList(procurementRecordLambdaQueryWrapper);
        if(CollectionUtils.isEmpty( procurementRecords)){
            return procurementPageDtoIPage;
        }
        for (ProcurementPageDto dto : procurementPageDtos) {
            // æ ¹æ®é‡‡è´­å°è´¦ID筛选对应的出库记录
            List<ProcurementRecordOut> collect1 = procurementRecords.stream()
                    .filter(ProcurementRecordOut -> ProcurementRecordOut.getProcurementRecordStorageId().equals(dto.getId()))
                    .collect(Collectors.toList());
            // å¦‚果没有相关的出库记录,跳过该条数据
            if(CollectionUtils.isEmpty(collect1)){
                dto.setInboundNum0(dto.getInboundNum());
                continue;
            }
            // è®¡ç®—已出库数量总和,并设置待出库数量
            BigDecimal totalInboundNum = collect1.stream()
                    .map(ProcurementRecordOut::getInboundNum)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            // å¾…出库数量 = æ€»æ•°é‡ - å·²å‡ºåº“数量
            dto.setInboundNum0(dto.getInboundNum().subtract(totalInboundNum));
        }
        return procurementPageDtoIPage;
    }
src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
@@ -65,6 +65,7 @@
            productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
            productProcessRouteItem.setProductOrderId(productOrder.getId());
            productProcessRouteItem.setProductRouteId(productProcessRoute.getId());
            productProcessRouteItem.setDragSort(processRouteItem.getDragSort());
            int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
            if (insert > 0) {
                // æŸ¥è¯¢ä»Šæ—¥å·²å­˜åœ¨çš„æœ€å¤§å·¥å•号
@@ -90,7 +91,8 @@
                ProductWorkOrder productWorkOrder = new ProductWorkOrder();
                productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
                productWorkOrder.setProductOrderId(productOrder.getId());
                productWorkOrder.setPlanQuantity(productOrder.getQuantity());
                ProductOrder order = productOrderMapper.selectById(productOrder);
                productWorkOrder.setPlanQuantity(order.getQuantity());
                productWorkOrder.setWorkOrderNo(workOrderNoStr);
                productWorkOrder.setStatus(1);
                productWorkOrderMapper.insert(productWorkOrder);
src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
@@ -14,7 +14,11 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.domain.SysUserDept;
import com.ruoyi.project.system.mapper.SysDeptMapper;
import com.ruoyi.project.system.mapper.SysUserDeptMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
@@ -36,6 +40,12 @@
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private SysDeptMapper deptMapper;
    @Autowired
    private SysUserDeptMapper userDeptMapper;
    @Autowired
    @Lazy
@@ -137,12 +147,53 @@
    }
    @Override
    public void simpleNoticeAll(String title, String message,  Long tenantId,String jumpPath) {
    public void simpleNoticeAll(String title, String message, Long rootDeptId, String jumpPath) {
        Long userId = SecurityUtils.getLoginUser().getUserId();
        List<SysUser> sysUsers = userMapper.selectList(Wrappers.<SysUser>lambdaQuery()
                .eq(SysUser::getStatus, "0")
                .eq(SysUser::getTenantId, tenantId));
        List<SysNotice> collect = sysUsers.stream().map(it -> convertSysNotice(title, message, it.getUserId(),tenantId, jumpPath,  userId)).collect(Collectors.toList());
        if (userId == null) {
            return;
        }
        //  æŸ¥æ‰€æœ‰å­éƒ¨é—¨
        List<SysDept> childrenDepts = deptMapper.selectChildrenDeptById(rootDeptId);
        //  ç»„装 deptIds
        List<Long> deptIds = childrenDepts.stream()
                .map(SysDept::getDeptId)
                .collect(Collectors.toList());
        deptIds.add(rootDeptId);
        //  æŸ¥ç”¨æˆ·ID
        List<Long> userIds = userDeptMapper.selectList(
                        Wrappers.<SysUserDept>lambdaQuery()
                                .in(SysUserDept::getDeptId, deptIds)
                ).stream()
                .map(SysUserDept::getUserId)
                .distinct()
                .collect(Collectors.toList());
        if (userIds.isEmpty()) {
            return;
        }
        //  æŸ¥ç”¨æˆ·
        List<SysUser> sysUsers = userMapper.selectList(
                Wrappers.<SysUser>lambdaQuery()
                        .eq(SysUser::getStatus, "0")
                        .in(SysUser::getUserId, userIds)
        );
        //  å‘通知
        List<SysNotice> collect = sysUsers.stream()
                .map(it -> convertSysNotice(
                        title,
                        message,
                        it.getUserId(),
                        it.getTenantId(),
                        jumpPath,
                        userId
                ))
                .collect(Collectors.toList());
        sysNoticeService.saveBatch(collect);
    }
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -198,10 +198,12 @@
            handleSalesLedgerProducts(purchaseLedger.getId(), productList, purchaseLedgerDto.getType());
        }
        //新增原材料检验
        for (SalesLedgerProduct saleProduct : productList) {
            //是否推送质检,如果true就添加
            if (saleProduct.getIsChecked()) {
                addQualityInspect(purchaseLedger, saleProduct);
        if (productList != null) {
            for (SalesLedgerProduct saleProduct : productList) {
                //是否推送质检,如果true就添加
                if (saleProduct.getIsChecked()) {
                    addQualityInspect(purchaseLedger, saleProduct);
                }
            }
        }
        // 5. è¿ç§»ä¸´æ—¶æ–‡ä»¶åˆ°æ­£å¼ç›®å½•
@@ -217,7 +219,7 @@
        qualityInspect.setInspectType(0);
        qualityInspect.setSupplier(purchaseLedger.getSupplierName());
        qualityInspect.setPurchaseLedgerId(purchaseLedger.getId());
        qualityInspect.setProductId(saleProduct.getId());
        qualityInspect.setProductId(saleProduct.getProductId());
        qualityInspect.setProductName(saleProduct.getProductCategory());
        qualityInspect.setModel(saleProduct.getSpecificationModel());
        qualityInspect.setProductModelId(saleProduct.getProductModelId());
src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
@@ -50,10 +50,7 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -258,48 +255,119 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delRegistration(Long[] ids) {
        // åˆ é™¤é‡‡è´­å°è´¦äº§å“å¼€ç¥¨è®°å½•对象
        LambdaQueryWrapper<ProductRecord> productRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productRecordLambdaQueryWrapper.in(ProductRecord::getId, Arrays.asList(ids));
        List<ProductRecord> productRecords = productRecordMapper.selectList(productRecordLambdaQueryWrapper);
        if(CollectionUtils.isEmpty(productRecords)){
        //  æŸ¥è¯¢è¦åˆ é™¤çš„产品来票记录
        LambdaQueryWrapper<ProductRecord> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.in(ProductRecord::getId, Arrays.asList(ids));
        List<ProductRecord> productRecords = productRecordMapper.selectList(productWrapper);
        if (CollectionUtils.isEmpty(productRecords)) {
            return 0;
        }
        LambdaQueryWrapper<TicketRegistration> ticketRegistrationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ticketRegistrationLambdaQueryWrapper.in(TicketRegistration::getId, productRecords.stream().map(ProductRecord::getTicketRegistrationId).collect(Collectors.toList()));
        List<TicketRegistration> ticketRegistrations = ticketRegistrationMapper.selectList(ticketRegistrationLambdaQueryWrapper);
        // ä¿®æ”¹äº§å“ä¿¡æ¯
        for (ProductRecord productRecord : productRecords) {
            BigDecimal subtract = ticketRegistrations.get(0).getInvoiceAmount().subtract(productRecords.get(0).getTicketsAmount());
            // å°äºŽç­‰äºŽ0删除 ï¼Œå¤§äºŽ0修改
            if(subtract.compareTo(BigDecimal.ZERO) <= 0){
                ticketRegistrationMapper.deleteById(ticketRegistrations.get(0));
                // åˆ é™¤ä»˜æ¬¾æµæ°´è®°å½•
                paymentRegistrationMapper.delete(new LambdaQueryWrapper<PaymentRegistration>().eq(PaymentRegistration::getTicketRegistrationId, ticketRegistrations.get(0).getId()));
            }else if(subtract.compareTo(BigDecimal.ZERO) > 0){
                ticketRegistrations.get(0).setInvoiceAmount(subtract);
                ticketRegistrationMapper.updateById(ticketRegistrations.get(0));
            }
            LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductLambdaQueryWrapper = new LambdaQueryWrapper<>();
            salesLedgerProductLambdaQueryWrapper.eq(SalesLedgerProduct::getId, productRecord.getSaleLedgerProjectId())
                    .eq(SalesLedgerProduct::getType, 2);
            List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(salesLedgerProductLambdaQueryWrapper);
            if(!CollectionUtils.isEmpty(salesLedgerProducts)){
                for (SalesLedgerProduct salesLedgerProduct : salesLedgerProducts) {
                    salesLedgerProduct.setFutureTickets(salesLedgerProduct.getFutureTickets().add(productRecord.getTicketsNum()));
                    salesLedgerProduct.setFutureTicketsAmount(salesLedgerProduct.getFutureTicketsAmount().add(productRecord.getTicketsAmount()));
                    salesLedgerProductMapper.updateById(salesLedgerProduct);
        //  æ”¶é›†å…³è”ID
        Set<Long> ticketRegistrationIds = productRecords.stream()
                .map(ProductRecord::getTicketRegistrationId)
                .collect(Collectors.toSet());
                }
        Set<Long> salesLedgerProductIds = productRecords.stream()
                .map(ProductRecord::getSaleLedgerProjectId)
                .collect(Collectors.toSet());
        //  æŸ¥è¯¢æ¥ç¥¨ç™»è®°
        List<TicketRegistration> ticketRegistrations =
                ticketRegistrationMapper.selectBatchIds(ticketRegistrationIds);
        //  å¤„理来票登记金额、付款流水
        for (TicketRegistration ticket : ticketRegistrations) {
            // è¯¥æ¥ç¥¨ç™»è®°ä¸‹æ‰€æœ‰äº§å“è®°å½•
            List<ProductRecord> recordsOfTicket = productRecords.stream()
                    .filter(r -> r.getTicketRegistrationId().equals(ticket.getId()))
                    .collect(Collectors.toList());
            // è®¡ç®—要回退的金额
            BigDecimal rollbackAmount = recordsOfTicket.stream()
                    .map(ProductRecord::getTicketsAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal remain = ticket.getInvoiceAmount().subtract(rollbackAmount);
            if (remain.compareTo(BigDecimal.ZERO) <= 0) {
                // åˆ é™¤æ¥ç¥¨ç™»è®°
                ticketRegistrationMapper.deleteById(ticket.getId());
                // åˆ é™¤ä»˜æ¬¾æµæ°´
                paymentRegistrationMapper.delete(
                        new LambdaQueryWrapper<PaymentRegistration>()
                                .eq(PaymentRegistration::getTicketRegistrationId, ticket.getId())
                );
            } else {
                ticket.setInvoiceAmount(remain);
                ticketRegistrationMapper.updateById(ticket);
            }
        }
        // åˆ é™¤é‡‡è´­å°è´¦äº§å“å¼€ç¥¨è®°å½•
        productRecordMapper.delete(productRecordLambdaQueryWrapper);
        //  å›žé€€é”€å”®å°è´¦äº§å“çš„æœªæ¥ç¥¨
        for (ProductRecord record : productRecords) {
            LambdaQueryWrapper<SalesLedgerProduct> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SalesLedgerProduct::getId, record.getSaleLedgerProjectId())
                    .eq(SalesLedgerProduct::getType, 2);
            SalesLedgerProduct product = salesLedgerProductMapper.selectOne(wrapper);
            if (product != null) {
                product.setFutureTickets(
                        product.getFutureTickets().add(record.getTicketsNum())
                );
                product.setFutureTicketsAmount(
                        product.getFutureTicketsAmount().add(record.getTicketsAmount())
                );
                salesLedgerProductMapper.updateById(product);
            }
        }
        //  åˆ é™¤äº§å“æ¥ç¥¨è®°å½•
        productRecordMapper.delete(productWrapper);
        //  é‡æ–°è®¡ç®— currentInvoiceAmount
        for (Long productId : salesLedgerProductIds) {
            refreshCurrentInvoiceAmount(productId);
        }
        return 1;
    }
    private void refreshCurrentInvoiceAmount(Long salesLedgerProductId) {
        // æŸ¥è¯¢è¯¥äº§å“æœ€æ–°ä¸€æ¡æ¥ç¥¨è®°å½•
        LambdaQueryWrapper<ProductRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductRecord::getSaleLedgerProjectId, salesLedgerProductId)
                .orderByDesc(ProductRecord::getCreatedAt)
                .last("limit 1");
        ProductRecord latestRecord = productRecordMapper.selectOne(wrapper);
        SalesLedgerProduct product =
                salesLedgerProductMapper.selectById(salesLedgerProductId);
        if (product == null) {
            return;
        }
        if (latestRecord == null) {
            //  æ²¡æœ‰ä»»ä½•来票记录
            product.setTicketsAmount(BigDecimal.ZERO);
        } else {
            //  æ°¸è¿œå–最新一条
            product.setTicketsAmount(latestRecord.getTicketsAmount());
        }
        salesLedgerProductMapper.updateById(product);
    }
    @Override
    public TicketRegistrationDto getRegistrationById(TicketRegistrationDto ticketRegistrationDto) {
        TicketRegistration ticketRegistration = ticketRegistrationMapper.selectById(ticketRegistrationDto.getId());
src/main/java/com/ruoyi/quality/controller/QualityInspectController.java
@@ -3,6 +3,9 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
import com.ruoyi.procurementrecord.service.ProcurementRecordService;
import com.ruoyi.procurementrecord.service.impl.ProcurementRecordServiceImpl;
import com.ruoyi.quality.dto.QualityInspectDto;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.quality.pojo.QualityInspectFile;
@@ -12,6 +15,7 @@
import com.ruoyi.quality.service.IQualityInspectParamService;
import com.ruoyi.quality.service.IQualityInspectService;
import com.ruoyi.quality.service.IQualityUnqualifiedService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@@ -34,6 +38,8 @@
    @Resource
    private IQualityInspectFileService qualityInspectFileService;
    @Autowired
    private ProcurementRecordService procurementRecordService;
    /**
@@ -62,6 +68,8 @@
        //删除检验附件
        qualityInspectFileService.remove(Wrappers.<QualityInspectFile>lambdaQuery()
        .in(QualityInspectFile::getInspectId,ids));
        //删除入库记录
        procurementRecordService.remove(Wrappers.<ProcurementRecordStorage>lambdaQuery().in(ProcurementRecordStorage::getQualityInspectId,ids));
        //删除检验单
        return AjaxResult.success(qualityInspectService.removeBatchByIds(ids));
    }
src/main/java/com/ruoyi/quality/service/IQualityInspectService.java
@@ -5,11 +5,8 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.quality.dto.QualityInspectDto;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
import com.ruoyi.staff.pojo.StaffOnJob;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
public interface IQualityInspectService extends IService<QualityInspect> {
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -1,10 +1,8 @@
package com.ruoyi.quality.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -21,22 +19,15 @@
import com.ruoyi.procurementrecord.service.ProcurementRecordService;
import com.ruoyi.quality.dto.QualityInspectDto;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.quality.mapper.QualityInspectParamMapper;
import com.ruoyi.quality.mapper.QualityTestStandardMapper;
import com.ruoyi.quality.mapper.QualityUnqualifiedMapper;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.quality.pojo.QualityInspectParam;
import com.ruoyi.quality.pojo.QualityTestStandard;
import com.ruoyi.quality.pojo.QualityUnqualified;
import com.ruoyi.quality.service.IQualityInspectParamService;
import com.ruoyi.quality.service.IQualityInspectService;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.staff.mapper.StaffJoinLeaveRecordMapper;
import com.ruoyi.staff.mapper.StaffOnJobMapper;
import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
import com.ruoyi.staff.pojo.StaffOnJob;
import com.ruoyi.staff.service.IStaffOnJobService;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
@@ -113,7 +104,7 @@
            if ("合格".equals(qualityInspect.getCheckResult())) {
                ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
                procurementRecordOutAdd.setType(1);
                procurementRecordOutAdd.setTypeName("采购入库");
                procurementRecordOutAdd.setTypeName("采购原材料检验合格入库");
                procurementRecordOutAdd.setNickName(loginUser.getNickName());
                procurementRecordOutAdd.setPurchaseLedgerId(Math.toIntExact(qualityInspect.getPurchaseLedgerId()));
                if (qualityInspect.getPurchaseLedgerId() == null) {
@@ -131,13 +122,14 @@
                details.setProductModelId(qualityInspect.getProductModelId());
                detailss.add( details);
                procurementRecordOutAdd.setDetails(detailss);
                procurementRecordOutAdd.setQualityInspectId(qualityInspect.getId());
                procurementRecordService.add(procurementRecordOutAdd);
            }
        }else if (qualityInspect.getInspectType() == 1) {
            //查询UnitPrice/TotalPrice
            ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
            procurementRecordOutAdd.setType(2);
            procurementRecordOutAdd.setTypeName("生产入库");
            procurementRecordOutAdd.setTypeName("生产过程检验合格入库");
            procurementRecordOutAdd.setNickName(loginUser.getNickName());
            List<Details> details = new ArrayList<>();
            Details details1 = new Details();
@@ -158,7 +150,8 @@
                    .updateTime(LocalDateTime.now())
                    .updateUser(loginUser.getUserId())
                    .createBy(procurementRecordOutAdd.getNickName())
                    .productModelId(details1.getProductModelId());
                    .productModelId(details1.getProductModelId())
                    .qualityInspectId(qualityInspect.getId());
            procurementRecordService.save(procurementRecordBuilder.build());
@@ -168,7 +161,7 @@
            SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectSalesLedgerProductByMainId(qualityInspect.getProductMainId());
            ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
            procurementRecordOutAdd.setType(2);
            procurementRecordOutAdd.setTypeName("生产入库");
            procurementRecordOutAdd.setTypeName("生产出厂检验合格入库");
            procurementRecordOutAdd.setNickName(loginUser.getNickName());
            List<Details> details = new ArrayList<>();
            Details details1 = new Details();
@@ -179,6 +172,7 @@
            details1.setProductModelId(salesLedgerProduct.getProductModelId());
            details.add(details1);
            procurementRecordOutAdd.setDetails(details);
            procurementRecordOutAdd.setQualityInspectId(qualityInspect.getId());
            procurementRecordService.add(procurementRecordOutAdd);
        }
        qualityInspect.setInspectState(1);//已提交
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
@@ -21,10 +21,14 @@
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.service.ICommonFileService;
import com.ruoyi.sales.service.ISalesLedgerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
@@ -43,6 +47,7 @@
@RestController
@RequestMapping("/sales/ledger")
@AllArgsConstructor
@Api(tags = "销售台账")
public class SalesLedgerController extends BaseController {
    private ISalesLedgerService salesLedgerService;
@@ -59,6 +64,18 @@
    private ReceiptPaymentMapper receiptPaymentMapper;
    /**
     * å¯¼å…¥é”€å”®å°è´¦
     */
    @Log(title = "导入销售台账", businessType = BusinessType.INSERT)
    @PostMapping("/import")
    @ApiOperation("导入销售台账")
    public AjaxResult importData(@RequestParam("file")
                                 @ApiParam(value = "Excel文件", required = true)
                                 MultipartFile file) {
        return salesLedgerService.importData(file);
    }
    /**
     * æŸ¥è¯¢é”€å”®å°è´¦åˆ—表
     */
    @GetMapping("/list")
src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java
@@ -88,7 +88,7 @@
            BigDecimal stockQuantity = stockUtils.getStockQuantity(item.getProductModelId()).get("stockQuantity");
            if(stockQuantity != null) {
//                ProcurementPageDtoCopy procurementDtoCopy = result.getRecords().get(0);
                if (item.getQuantity().compareTo(stockQuantity) >= 0 && item.getApproveStatus() == 0) {
                if (item.getQuantity().compareTo(stockQuantity) <= 0 && item.getApproveStatus() == 0) {
                    item.setApproveStatus(1);
                    salesLedgerProductService.addOrUpdateSalesLedgerProduct(item);
                }
src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java
@@ -89,19 +89,21 @@
        //  å®¡æ‰¹é€šè¿‡
        if (req.getApproveStatus() == 3) {
            // æŸ¥è¯¢é‡‡è´­å…¥åº“记录
            LambdaQueryWrapper<ProcurementRecordStorage> lambdaQueryWrapper = new LambdaQueryWrapper<ProcurementRecordStorage>()
                    .eq(ProcurementRecordStorage::getSalesLedgerProductId, req.getSalesLedgerProductId());
            ProcurementRecordStorage procurementRecordStorage = procurementRecordStorageService.getOne(lambdaQueryWrapper);
            if (procurementRecordStorage == null) {
                // ä¿è¯å‰é¢çš„修改全部回滚
                throw new ServiceException("采购记录不存在,审批回滚");
            }
//            // æŸ¥è¯¢é‡‡è´­å…¥åº“记录
//            LambdaQueryWrapper<ProcurementRecordStorage> lambdaQueryWrapper = new LambdaQueryWrapper<ProcurementRecordStorage>()
//                    .eq(ProcurementRecordStorage::getSalesLedgerProductId, req.getSalesLedgerProductId());
//            ProcurementRecordStorage procurementRecordStorage = procurementRecordStorageService.getOne(lambdaQueryWrapper);
//
//            if (procurementRecordStorage == null) {
//                // ä¿è¯å‰é¢çš„修改全部回滚
//                throw new ServiceException("采购记录不存在,审批回滚");
//            }
            //  ç”Ÿæˆå‡ºåº“记录
            ProcurementRecordOutAdd procurementRecordOutAdd = new ProcurementRecordOutAdd();
            procurementRecordOutAdd.setId(procurementRecordStorage.getId());
//            procurementRecordOutAdd.setId(procurementRecordStorage.getId());
            procurementRecordOutAdd.setId(0);
            procurementRecordOutAdd.setProductModelId(salesLedgerProduct.getProductModelId());
            procurementRecordOutAdd.setSalesLedgerProductId((long) Math.toIntExact(salesLedgerProduct.getId()));
            procurementRecordOutAdd.setType(2);
            procurementRecordOutAdd.setUserId(Math.toIntExact(getUserId()));
src/main/java/com/ruoyi/sales/dto/SalesLedgerImportDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package com.ruoyi.sales.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.sales.pojo.CommonFile;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
/**
 * @author :yys
 * @date : 2026/1/19 9:50
 */
@Data
public class SalesLedgerImportDto extends SalesLedgerProductImportDto{
    @Excel(name = "销售单号")
    private String salesContractNo;
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "录入日期", width = 30, dateFormat = "yyyy-MM-dd")
    private Date entryDate;
    @Excel(name = "业务员")
    private String salesman;
    @Excel(name = "客户名称")
    private String customerName;
    @Excel(name = "录入人")
    private String entryPerson;
    @Excel(name = "备注")
    private String remarks;
    @ApiModelProperty(value = "签订日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "签订日期", width = 30, dateFormat = "yyyy-MM-dd")
    private Date executionDate;
    @Excel(name = "合同金额")
    private BigDecimal contractAmount;
}
src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,78 @@
package com.ruoyi.sales.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
 * @author :yys
 * @date : 2026/1/19 9:59
 */
@Data
public class SalesLedgerProductImportDto {
    @Excel(name = "销售单号")
    private String salesContractNo;
    /**
     * äº§å“å¤§ç±»
     */
    @Excel(name = "产品大类")
    private String productCategory;
    /**
     * è§„格型号
     */
    @Excel(name = "规格型号")
    private String specificationModel;
    /**
     * å•位
     */
    @Excel(name = "单位")
    private String unit;
    /**
     * æ•°é‡
     */
    @Excel(name = "数量")
    private BigDecimal quantity;
    /**
     * ç¨Žçއ
     */
    @Excel(name = "税率")
    private BigDecimal taxRate;
    /**
     * å«ç¨Žå•ä»·
     */
    @Excel(name = "含税单价")
    private BigDecimal taxInclusiveUnitPrice;
    /**
     * å«ç¨Žæ€»ä»·
     */
    @Excel(name = "含税总价")
    private BigDecimal taxInclusiveTotalPrice;
    /**
     * å‘票类型
     */
    @Excel(name = "发票类型")
    private String invoiceType;
    /**
     * æ˜¯å¦è´¨æ£€
     */
    @Excel(name = "是否质检", readConverterExp = "0=否,1=是")
    private Boolean isChecked;
}
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -129,16 +129,16 @@
    private BigDecimal futureTicketsAmount=BigDecimal.ZERO;
    @ApiModelProperty(value = "开票数")
    private BigDecimal invoiceNum;
    private BigDecimal invoiceNum = BigDecimal.ZERO;
    @ApiModelProperty(value = "未开票数")
    private BigDecimal noInvoiceNum;
    private BigDecimal noInvoiceNum = BigDecimal.ZERO;
    @ApiModelProperty(value = "开票金额")
    private BigDecimal invoiceAmount;
    private BigDecimal invoiceAmount = BigDecimal.ZERO;
    @ApiModelProperty(value = "未开票金额")
    private BigDecimal noInvoiceAmount;
    private BigDecimal noInvoiceAmount = BigDecimal.ZERO;
    @ApiModelProperty(value = "本次开票数")
    @TableField(exist = false)
src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
@@ -3,9 +3,11 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.sales.dto.MonthlyAmountDto;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.pojo.SalesLedger;
import org.springframework.web.multipart.MultipartFile;
import java.math.BigDecimal;
import java.util.List;
@@ -35,4 +37,6 @@
    List<MonthlyAmountDto> getAmountHalfYear(Integer type);
    IPage<SalesLedger> selectSalesLedgerListPage(Page page, SalesLedgerDto salesLedgerDto);
    AjaxResult importData(MultipartFile file);
}
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -98,10 +98,10 @@
                        if(ledgerProduct.getId().intValue() == registrationProductDto.getSalesLedgerProductId()){
                            invoiceNum =  invoiceNum.add(registrationProductDto.getInvoiceNum());
                            invoiceAmount = invoiceAmount.add(registrationProductDto.getInvoiceAmount());
                            noInvoiceNum = ledgerProduct.getQuantity().subtract(invoiceNum);
                            noInvoiceAmount = ledgerProduct.getTaxInclusiveTotalPrice().subtract(invoiceAmount);
                        }
                    }
                    noInvoiceNum = ledgerProduct.getQuantity().subtract(invoiceNum);
                    noInvoiceAmount = ledgerProduct.getTaxInclusiveTotalPrice().subtract(invoiceAmount);
                    ledgerProduct.setInvoiceNum(invoiceNum);
                    ledgerProduct.setInvoiceAmount(invoiceAmount);
                    ledgerProduct.setNoInvoiceNum(noInvoiceNum);
@@ -291,6 +291,7 @@
                productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
                productProcessRouteItem.setProductOrderId(productOrder.getId());
                productProcessRouteItem.setProductRouteId(productProcessRoute.getId());
                productProcessRouteItem.setDragSort(processRouteItem.getDragSort());
                int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
                if (insert > 0) {
                    // æŸ¥è¯¢ä»Šæ—¥å·²å­˜åœ¨çš„æœ€å¤§å·¥å•号
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -12,24 +12,33 @@
import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.account.service.AccountIncomeService;
import com.ruoyi.basic.mapper.CustomerMapper;
import com.ruoyi.basic.mapper.ProductMapper;
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.common.enums.FileNameType;
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.framework.security.LoginUser;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.other.mapper.TempFileMapper;
import com.ruoyi.other.pojo.TempFile;
import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysDeptMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.sales.dto.MonthlyAmountDto;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.dto.SalesLedgerImportDto;
import com.ruoyi.sales.dto.SalesLedgerProductImportDto;
import com.ruoyi.sales.mapper.*;
import com.ruoyi.sales.pojo.*;
import com.ruoyi.sales.service.ISalesLedgerProductService;
@@ -44,10 +53,13 @@
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -130,6 +142,9 @@
    private final RedisTemplate<String, String> redisTemplate;
    @Autowired
    private ProductModelMapper productModelMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private ProductStructureMapper productStructureMapper;
@@ -325,6 +340,99 @@
        return salesLedgerMapper.selectSalesLedgerListPage(page, salesLedgerDto);
    }
    @Autowired
    private SysUserMapper sysUserMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult importData(MultipartFile file) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        try {
            InputStream inputStream = file.getInputStream();
            ExcelUtil<SalesLedgerImportDto> salesLedgerImportDtoExcelUtil = new ExcelUtil<>(SalesLedgerImportDto.class);
            Map<String, List<SalesLedgerImportDto>> stringListMap = salesLedgerImportDtoExcelUtil.importExcelMultiSheet(Arrays.asList("销售台账数据","销售产品数据"), inputStream, 0);
            if(CollectionUtils.isEmpty(stringListMap)) return AjaxResult.error("销售表格为空!");
            // ä¸šåŠ¡å±‚åˆå¹¶
            List<SalesLedgerImportDto> salesLedgerImportDtoList = stringListMap.get("销售台账数据");
            if(CollectionUtils.isEmpty(salesLedgerImportDtoList)) return AjaxResult.error("销售台账数据为空!");
            List<SalesLedgerImportDto> salesLedgerProductImportDtoList = stringListMap.get("销售产品数据");
            if(CollectionUtils.isEmpty(salesLedgerProductImportDtoList)) return AjaxResult.error("销售产品数据为空!");
            // å®¢æˆ·æ•°æ®
            List<Customer> customers = customerMapper.selectList(new LambdaQueryWrapper<Customer>().in(Customer::getCustomerName,
                    salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getCustomerName).toArray(String[]::new)));
            // è§„格型号数据
            List<ProductModel> productModels = productModelMapper.selectList(new LambdaQueryWrapper<ProductModel>().in(ProductModel::getModel,
                    salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getSpecificationModel).toArray(String[]::new)));
            // äº§å“å¤§ç±»æ•°æ®
            List<Product> productList = productMapper.selectList(new LambdaQueryWrapper<Product>().in(Product::getProductName,
                    salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getProductCategory).toArray(String[]::new)));
            // å½•入人数据
            List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getNickName,
                    salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getEntryPerson).toArray(String[]::new)));
            for (SalesLedgerImportDto salesLedgerImportDto : salesLedgerImportDtoList) {
                SalesLedger salesLedger = new SalesLedger();
                BeanUtils.copyProperties(salesLedgerImportDto, salesLedger);
                // é€šè¿‡å®¢æˆ·åç§°æŸ¥è¯¢å®¢æˆ·ID,客户合同号
                salesLedger.setCustomerId(customers.stream()
                        .filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName()))
                        .findFirst()
                        .map(Customer::getId)
                        .orElse(null));
                salesLedger.setCustomerContractNo(customers.stream()
                        .filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName()))
                        .findFirst()
                        .map(Customer::getTaxpayerIdentificationNumber)
                        .orElse(null));
                Long aLong = sysUsers.stream()
                        .filter(sysUser -> sysUser.getNickName().equals(salesLedger.getEntryPerson()))
                        .findFirst()
                        .map(SysUser::getUserId)
                        .orElse(null);
                if(aLong == null) throw new RuntimeException("录入人:"+salesLedger.getEntryPerson()+",无对应用户!");
                salesLedger.setEntryPerson(aLong.toString());
                salesLedgerMapper.insert(salesLedger);
                // é”€å”®äº§å“æ•°æ®ç»‘定,通过销售单号获取对应销售产品数据
                List<SalesLedgerProductImportDto> salesLedgerProductImportDtos = salesLedgerProductImportDtoList.stream()
                        .filter(salesLedgerProductImportDto -> salesLedgerProductImportDto.getSalesContractNo().equals(salesLedger.getSalesContractNo()))
                        .collect(Collectors.toList());
                if(CollectionUtils.isEmpty(salesLedgerProductImportDtos)) throw new RuntimeException("销售单号:"+salesLedgerImportDto.getSalesContractNo()+",无对应产品数据!");
                for (SalesLedgerProductImportDto salesLedgerProductImportDto : salesLedgerProductImportDtos) {
                    SalesLedgerProduct salesLedgerProduct = new SalesLedgerProduct();
                    BeanUtils.copyProperties(salesLedgerProductImportDto, salesLedgerProduct);
                    salesLedgerProduct.setSalesLedgerId(salesLedger.getId());
                    salesLedgerProduct.setType(1);
                    // è®¡ç®—不含税总价
                    salesLedgerProduct.setTaxExclusiveTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice().divide(new BigDecimal(1).add(salesLedgerProduct.getTaxRate().divide(new BigDecimal(100))), 2, RoundingMode.HALF_UP));
                    salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity());
                    salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxExclusiveTotalPrice());
                    salesLedgerProduct.setProductId(productList.stream()
                            .filter(product -> product.getProductName().equals(salesLedgerProduct.getProductCategory()))
                            .findFirst()
                            .map(Product::getId)
                            .orElse(null));
                    salesLedgerProduct.setProductModelId(productModels.stream()
                            .filter(productModel -> productModel.getModel().equals(salesLedgerProduct.getSpecificationModel()))
                            .findFirst()
                            .map(ProductModel::getId)
                            .orElse(null));
                    salesLedgerProduct.setRegister(loginUser.getNickName());
                    salesLedgerProduct.setRegisterDate(LocalDateTime.now());
                    salesLedgerProduct.setApproveStatus(0);
                    salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProductImportDto.getTaxInclusiveTotalPrice());
                    salesLedgerProductMapper.insert(salesLedgerProduct);
                }
            }
            return AjaxResult.success("导入成功");
        }catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.success("导入失败");
    }
    // å†…部类用于存储聚合结果
    private static class GroupedCustomer {
        private final Long customerId;
src/main/java/com/ruoyi/staff/controller/PersonalAttendanceRecordsController.java
@@ -3,8 +3,6 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.staff.pojo.PersonalAttendanceRecords;
import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
import com.ruoyi.staff.pojo.StaffOnJob;
import com.ruoyi.staff.service.PersonalAttendanceRecordsService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
src/main/java/com/ruoyi/staff/controller/StaffJoinLeaveRecordController.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/staff/controller/StaffLeaveController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
package com.ruoyi.staff.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.staff.dto.StaffLeaveDto;
import com.ruoyi.staff.service.StaffLeaveService;
import io.swagger.annotations.Api;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * å‘˜å·¥ç¦»èŒ
 */
@RestController
@RequestMapping("/staff/staffLeave")
@Api(tags = "员工离职")
public class StaffLeaveController {
    @Resource
    private StaffLeaveService staffLeaveService;
    /**
     * æ–°å¢žç¦»èŒåˆ†é¡µæŸ¥è¯¢
     * @param page
     * @param staffLeaveDto
     * @return
     */
    @GetMapping("/listPage")
    public AjaxResult staffLeaveListPage(Page page, StaffLeaveDto staffLeaveDto) {
        return AjaxResult.success(staffLeaveService.staffLeaveListPage(page, staffLeaveDto));
    }
    /**
     * æ–°å¢žç¦»èŒ
     * @param staffLeaveDto
     * @return
     */
    @PostMapping("")
    public AjaxResult add(@RequestBody StaffLeaveDto staffLeaveDto) {
        return AjaxResult.success(staffLeaveService.add(staffLeaveDto));
    }
    /**
     * æ›´æ–°ç¦»èŒä¿¡æ¯
     * @param id
     * @param staffLeaveDto
     * @return
     */
    @PutMapping("/{id}")
    public AjaxResult update(@PathVariable("id") Long id, @RequestBody StaffLeaveDto staffLeaveDto) {
        return AjaxResult.success(staffLeaveService.update(id, staffLeaveDto));
    }
    /**
     * åˆ é™¤å…¥èŒ
     * @param ids
     * @return
     */
    @DeleteMapping("/del")
    public AjaxResult del(@RequestBody List<Integer> ids) {
        if(CollectionUtils.isEmpty(ids)){
            return AjaxResult.error("请选择至少一条数据");
        }
        return AjaxResult.success(staffLeaveService.del(ids));
    }
    /**
     * ç¦»èŒå¯¼å‡º
     * @param staffLeaveDto
     */
    @PostMapping("/export")
    public void export(HttpServletResponse response, StaffLeaveDto staffLeaveDto) {
        staffLeaveService.export(response, staffLeaveDto);
    }
}
src/main/java/com/ruoyi/staff/controller/StaffOnJobController.java
@@ -5,9 +5,8 @@
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.staff.dto.StaffOnJobDto;
import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
import com.ruoyi.staff.pojo.StaffContract;
import com.ruoyi.staff.pojo.StaffOnJob;
import com.ruoyi.staff.service.IStaffJoinLeaveRecordService;
import com.ruoyi.staff.service.IStaffOnJobService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -25,7 +24,7 @@
 */
@RestController
@RequestMapping("/staff/staffOnJob")
@Api(tags = "员工台账/合同管理")
@Api(tags = "员工台账")
public class StaffOnJobController {
    @Resource
@@ -48,8 +47,8 @@
     * @return
     */
    @GetMapping("/list")
    public AjaxResult staffOnJobList() {
        return AjaxResult.success(staffOnJobService.staffOnJobList());
    public AjaxResult staffOnJobList(StaffOnJob staffOnJob) {
        return AjaxResult.success(staffOnJobService.staffOnJobList(staffOnJob));
    }
    /**
@@ -91,11 +90,22 @@
     * @return
     */
    @GetMapping("/{id}")
    public AjaxResult staffJoinLeaveRecordDetail(@PathVariable("id") Long id) {
    public AjaxResult staffOnJobDetail(@PathVariable("id") Long id) {
        return AjaxResult.success(staffOnJobService.staffOnJobDetail(id));
    }
    /**
     * ç»­ç­¾åˆåŒ
     * @param id
     * @param staffContract
     * @return
     */
    @PostMapping("/renewContract/{id}")
    public AjaxResult renewContract(@PathVariable("id") Long id, @RequestBody StaffContract staffContract) {
        return AjaxResult.success(staffOnJobService.renewContract(id, staffContract));
    }
    /**
     * åœ¨èŒå‘˜å·¥å¯¼å…¥
     */
    @PostMapping("/import")
src/main/java/com/ruoyi/staff/dto/StaffJoinLeaveRecordDto.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/staff/dto/StaffLeaveDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,98 @@
package com.ruoyi.staff.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.staff.pojo.StaffLeave;
import lombok.Data;
import java.util.Date;
@Data
public class StaffLeaveDto extends StaffLeave {
    @Excel(name = "状态", readConverterExp = "0=离职,1=在职", sort = 1)
    private Integer staffState;
    /**
     * å‘˜å·¥ç¼–号
     */
    @Excel(name = "员工编号", type = Excel.Type.EXPORT, cellType = Excel.ColumnType.STRING, sort = 2)
    private String staffNo;
    /**
     * å‘˜å·¥å§“名
     */
    @Excel(name = "员工姓名", sort = 3)
    private String staffName;
    /**
     * æ€§åˆ«
     */
    @Excel(name = "性别", sort = 4)
    private String sex;
    /**
     * ç±è´¯
     */
    @Excel(name = "籍贯", sort = 5)
    private String nativePlace;
    /**
     * å®¶åº­ä½å€
     */
    @Excel(name = "家庭住址", sort = 6)
    private String adress;
    /**
     * å²—位
     */
    @Excel(name = "部门",sort = 7)
    private String deptName;
    /**
     * å²—位
     */
    @Excel(name = "岗位",sort = 8)
    private String postName;
    /**
     * ç¬¬ä¸€å­¦åކ
     */
    @Excel(name = "第一学历", sort = 9)
    private String firstStudy;
    /**
     * ä¸“业
     */
    @Excel(name = "专业", sort = 10)
    private String profession;
    /**
     * èº«ä»½è¯å·ç 
     */
    @Excel(name = "身份证号码", sort = 11)
    private String identityCard;
    /**
     * å¹´é¾„
     */
    @Excel(name = "年龄", sort = 12)
    private String age;
    /**
     * è”系电话
     */
    @Excel(name = "联系电话", sort = 13)
    private String phone;
    /**
     * ç´§æ€¥è”系人
     */
    @Excel(name = "紧急联系人", sort = 14)
    private String emergencyContact;
    /**
     * ç´§æ€¥è”系人电话
     */
    @Excel(name = "紧急联系人电话", sort = 15)
    private String emergencyContactPhone;
}
src/main/java/com/ruoyi/staff/dto/StaffOnJobDto.java
@@ -2,7 +2,6 @@
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
import com.ruoyi.staff.pojo.StaffOnJob;
import lombok.Data;
@@ -10,17 +9,17 @@
@Data
public class StaffOnJobDto extends StaffOnJob {
    @Excel(name = "岗位",sort = 7)
    @Excel(name = "部门",sort = 7)
    private String deptName;
    @Excel(name = "岗位",sort = 8)
    private String postName;
    @Excel(name = "合同年限")
    private String contractTerm;
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "合同开始日期", width = 30, dateFormat = "yyyy-MM-dd")
    private Date contractStartTime;
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "合同结束日期", width = 30, dateFormat = "yyyy-MM-dd")
    private Date contractEndTime;
}
src/main/java/com/ruoyi/staff/mapper/StaffJoinLeaveRecordMapper.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/staff/mapper/StaffLeaveMapper.java
@@ -1,10 +1,21 @@
package com.ruoyi.staff.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.staff.dto.StaffLeaveDto;
import com.ruoyi.staff.dto.StaffOnJobDto;
import com.ruoyi.staff.pojo.StaffLeave;
import com.ruoyi.staff.pojo.StaffOnJob;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface StaffLeaveMapper extends BaseMapper<StaffLeave> {
    IPage<StaffLeaveDto> staffLeaveListPage(Page page, @Param("c") StaffLeaveDto staffLeaveDto);
    List<StaffLeaveDto> staffLeaveList(@Param("c") StaffLeaveDto staffLeaveDto);
}
src/main/java/com/ruoyi/staff/pojo/StaffJoinLeaveRecord.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/staff/pojo/StaffLeave.java
@@ -21,6 +21,12 @@
    @ApiModelProperty(value = "在职员工ID")
    private Long staffOnJobId;
    @ApiModelProperty(value = "离职原因")
    private String reason;
    @ApiModelProperty(value = "离职备注")
    private String remark;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java
@@ -63,6 +63,11 @@
     */
    private Integer sysPostId;
     /**
     * éƒ¨é—¨
     */
    private Integer sysDeptId;
    /**
     * å®¶åº­ä½å€
     */
@@ -72,56 +77,56 @@
    /**
     * ç¬¬ä¸€å­¦åކ
     */
    @Excel(name = "第一学历", sort = 8)
    @Excel(name = "第一学历", sort = 9)
    private String firstStudy;
    /**
     * ä¸“业
     */
    @Excel(name = "专业", sort = 9)
    @Excel(name = "专业", sort = 10)
    private String profession;
    /**
     * èº«ä»½è¯å·ç 
     */
    @Excel(name = "身份证号码", sort = 10)
    @Excel(name = "身份证号码", sort = 11)
    private String identityCard;
    /**
     * å¹´é¾„
     */
    @Excel(name = "年龄", sort = 11)
    @Excel(name = "年龄", sort = 12)
    private String age;
    /**
     * è”系电话
     */
    @Excel(name = "联系电话", sort = 12)
    @Excel(name = "联系电话", sort = 13)
    private String phone;
    /**
     * ç´§æ€¥è”系人
     */
    @Excel(name = "紧急联系人", sort = 13)
    @Excel(name = "紧急联系人", sort = 14)
    private String emergencyContact;
    /**
     * ç´§æ€¥è”系人电话
     */
    @Excel(name = "紧急联系人电话", sort = 14)
    @Excel(name = "紧急联系人电话", sort = 15)
    private String emergencyContactPhone;
    /**
     * åˆåŒå¹´é™
     */
    @Excel(name = "合同年限", sort = 15)
    @Excel(name = "合同年限", sort = 16)
    private String contractTerm;
    /**
     * åˆåŒåˆ°æœŸæ—¥æœŸ
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "合同到期日期", width = 30, dateFormat = "yyyy-MM-dd", sort = 16)
    @Excel(name = "合同到期日期", width = 30, dateFormat = "yyyy-MM-dd", sort = 17)
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date contractExpireTime;
@@ -129,7 +134,7 @@
     * ç»“束试用时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "结束试用时间", width = 30, dateFormat = "yyyy-MM-dd", sort = 17)
    @Excel(name = "结束试用时间", width = 30, dateFormat = "yyyy-MM-dd", sort = 18)
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date trialEndDate;
@@ -137,7 +142,7 @@
     * å¼€å§‹è¯•用日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "开始试用日期", width = 30, dateFormat = "yyyy-MM-dd", sort = 18)
    @Excel(name = "开始试用日期", width = 30, dateFormat = "yyyy-MM-dd", sort = 19)
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date trialStartDate;
@@ -145,7 +150,7 @@
     * ç­¾è®¢æ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "签订时间", width = 30, dateFormat = "yyyy-MM-dd", sort = 19)
    @Excel(name = "签订时间", width = 30, dateFormat = "yyyy-MM-dd", sort = 20)
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date signDate;
@@ -158,7 +163,7 @@
    /**
     * è¯•用期工资
     */
    @Excel(name = "试用期工资", sort = 20)
    @Excel(name = "试用期工资", sort = 21)
    private BigDecimal proSalary;
    /**
@@ -170,7 +175,7 @@
    /**
     * å¤‡æ³¨ï¼ˆç¦åˆ©å¾…遇)
     */
    @Excel(name = "备注(福利待遇)", sort = 21)
    @Excel(name = "备注(福利待遇)", sort = 22)
    private String remark;
src/main/java/com/ruoyi/staff/service/IStaffJoinLeaveRecordService.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/staff/service/IStaffOnJobService.java
@@ -4,9 +4,8 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.staff.dto.StaffOnJobDto;
import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
import com.ruoyi.staff.pojo.StaffContract;
import com.ruoyi.staff.pojo.StaffOnJob;
import org.bouncycastle.crypto.digests.LongDigest;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
@@ -25,9 +24,11 @@
    int delStaffOnJobs(List<Integer> ids);
    int renewContract(Long id, StaffContract staffContract);
    void staffOnJobExport(HttpServletResponse response, StaffOnJob staffOnJob);
    List<StaffJoinLeaveRecord> staffOnJobList();
    List<StaffOnJobDto> staffOnJobList(StaffOnJob staffOnJob);
    Boolean importData(MultipartFile file);
src/main/java/com/ruoyi/staff/service/StaffContractService.java
@@ -4,14 +4,7 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.staff.dto.StaffContractDto;
import com.ruoyi.staff.dto.StaffOnJobDto;
import com.ruoyi.staff.pojo.StaffContract;
import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
import com.ruoyi.staff.pojo.StaffOnJob;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
public interface StaffContractService extends IService<StaffContract> {
src/main/java/com/ruoyi/staff/service/StaffLeaveService.java
@@ -1,7 +1,32 @@
package com.ruoyi.staff.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.staff.dto.StaffLeaveDto;
import com.ruoyi.staff.pojo.StaffLeave;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
public interface StaffLeaveService extends IService<StaffLeave> {
    IPage<StaffLeaveDto> staffLeaveListPage(Page page, StaffLeaveDto staffLeaveDto);
    /**
     * æ–°å¢žç¦»èŒ
     * @param staffLeaveDto
     * @return
     */
    int add(StaffLeaveDto staffLeaveDto);
    /**
     * æ›´æ–°ç¦»èŒä¿¡æ¯
     * @param id
     * @param staffLeaveDto
     * @return
     */
    int update(Long id, StaffLeaveDto staffLeaveDto);
    int del(List<Integer> ids);
    void export(HttpServletResponse response, StaffLeaveDto staffLeaveDto);
}
src/main/java/com/ruoyi/staff/service/impl/StaffJoinLeaveRecordServiceImpl.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
@@ -1,15 +1,102 @@
package com.ruoyi.staff.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.staff.dto.StaffLeaveDto;
import com.ruoyi.staff.mapper.StaffLeaveMapper;
import com.ruoyi.staff.mapper.StaffOnJobMapper;
import com.ruoyi.staff.pojo.StaffOnJob;
import com.ruoyi.staff.service.StaffLeaveService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.staff.pojo.StaffLeave;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import static com.ruoyi.common.enums.StaffLeaveReason.StaffLeaveReasonOther;
@AllArgsConstructor
@Service
public class StaffLeaveServiceImpl extends ServiceImpl<StaffLeaveMapper, StaffLeave> implements StaffLeaveService {
    private StaffLeaveMapper staffLeaveMapper;
    private StaffOnJobMapper staffOnJobMapper;
    //新增离职列表分页查询
    @Override
    public IPage<StaffLeaveDto> staffLeaveListPage(Page page, StaffLeaveDto staffLeaveDto) {
        return staffLeaveMapper.staffLeaveListPage(page,staffLeaveDto);
    }
    //新增离职
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int add(StaffLeaveDto staffLeaveDto) {
        // æ ¡éªŒåœ¨èŒå‘˜å·¥æ˜¯å¦å­˜åœ¨
        StaffOnJob staffOnJob = staffOnJobMapper.selectById(staffLeaveDto.getStaffOnJobId());
        if (staffOnJob == null) {
            throw new IllegalArgumentException("员工不存在");
        }
        // æ ¡éªŒå‘˜å·¥æ˜¯å¦ç¦»èŒ
        if (staffOnJob.getStaffState() == 0) {
            throw new IllegalArgumentException("员工已离职");
        }
        // æ–°å¢žç¦»èŒè®°å½•
        StaffLeave staffLeave = new StaffLeave();
        staffLeave.setStaffOnJobId(staffLeaveDto.getStaffOnJobId());
        String reason = staffLeaveDto.getReason();
        if (!StaffLeaveReasonOther.getCode().equals(reason)){
            staffLeave.setRemark("");
        }
        staffLeaveMapper.insert(staffLeave);
        // æ›´æ–°ç¦»èŒçŠ¶æ€ä¸ºç¦»èŒ
        staffOnJob.setStaffState(0);
       return staffOnJobMapper.updateById(staffOnJob);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(Long id, StaffLeaveDto staffLeaveDto) {
        // åˆ¤æ–­å¯¹è±¡æ˜¯å¦å­˜åœ¨
        StaffLeave leave = staffLeaveMapper.selectById(id);
        if (leave == null){
            throw new BaseException("该离职记录不存在,无法更新!!!");
        }
        String reason = staffLeaveDto.getReason();
        leave.setReason(reason);
        // æ ¡éªŒç¦»èŒåŽŸå› æ˜¯å¦ä¸ºå…¶ä»–ï¼Œå¦‚æžœæ˜¯å…¶ä»–ï¼Œå¤‡æ³¨èµ‹å€¼
        if (StaffLeaveReasonOther.getCode().equals(reason)){
            leave.setRemark(staffLeaveDto.getRemark());
        } else {
            leave.setRemark("");
        }
        return staffLeaveMapper.updateById(leave);
    }
    //删除离职
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int del(List<Integer> ids) {
        // åˆ é™¤ç¦»èŒæ•°æ®
        return staffLeaveMapper.deleteBatchIds(ids);
    }
    //导出
    @Override
    public void export(HttpServletResponse response, StaffLeaveDto staffLeaveDto) {
        List<StaffLeaveDto> staffLeaves =staffLeaveMapper.staffLeaveList(staffLeaveDto);
        ExcelUtil<StaffLeaveDto> util = new ExcelUtil<StaffLeaveDto>(StaffLeaveDto.class);
        util.exportExcel(response, staffLeaves, "员工离职导出");
    }
}
src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
@@ -1,7 +1,6 @@
package com.ruoyi.staff.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -13,11 +12,9 @@
import com.ruoyi.project.system.mapper.SysPostMapper;
import com.ruoyi.staff.dto.StaffOnJobDto;
import com.ruoyi.staff.mapper.StaffContractMapper;
import com.ruoyi.staff.mapper.StaffJoinLeaveRecordMapper;
import com.ruoyi.staff.mapper.StaffLeaveMapper;
import com.ruoyi.staff.mapper.StaffOnJobMapper;
import com.ruoyi.staff.pojo.StaffContract;
import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
import com.ruoyi.staff.pojo.StaffLeave;
import com.ruoyi.staff.pojo.StaffOnJob;
import com.ruoyi.staff.service.IStaffOnJobService;
@@ -38,8 +35,6 @@
import java.time.ZoneId;
import java.util.*;
import static com.ruoyi.common.enums.StaffJoinLeaveRecordDimissionReason.StaffJoinLeaveRecordDimissionReasonOther;
@AllArgsConstructor
@Service
public class StaffOnJobServiceImpl extends ServiceImpl<StaffOnJobMapper, StaffOnJob>  implements IStaffOnJobService {
@@ -49,7 +44,6 @@
    private SysPostMapper sysPostMapper;
    private StaffJoinLeaveRecordMapper staffJoinLeaveRecordMapper;
    private StaffContractMapper staffContractMapper;
    private StaffLeaveMapper staffLeaveMapper;
@@ -71,6 +65,7 @@
            throw new BaseException("编号为"+staffOnJobPrams.getStaffNo()+"的员工已经存在,无法新增!!!");
        }
        // åˆ›å»ºå…¥èŒæ•°æ®
        staffOnJobPrams.setContractExpireTime(staffOnJobPrams.getContractEndTime());
        staffOnJobMapper.insert(staffOnJobPrams);
        // åˆ›å»ºåˆåŒè®°å½•
@@ -92,20 +87,22 @@
            throw new BaseException("编号为"+staffOnJobParams.getStaffNo()+"的员工不存在,无法更新!!!");
        }
        // æ›´æ–°å‘˜å·¥æ•°æ®
        String[] ignoreProperties = {"id"};//排除id属性
        BeanUtils.copyProperties(staffOnJobParams,job,ignoreProperties);
        staffOnJobMapper.updateById(job);
        // èŽ·å–æœ€æ–°åˆåŒæ•°æ®ï¼Œå¹¶ä¸”æ›´æ–°
        StaffContract contract = staffContractMapper.selectOne(Wrappers.<StaffContract>lambdaQuery()
                .eq(StaffContract::getStaffOnJobId, id)
                .last("limit 1")
                .orderByDesc(StaffContract::getId));
        if (contract != null){
            BeanUtils.copyProperties(staffOnJobParams,contract,ignoreProperties);
            return staffContractMapper.updateById(contract);
            staffContractMapper.updateById(contract);
        }
        return 0;
        // æ›´æ–°å‘˜å·¥æ•°æ®
        BeanUtils.copyProperties(staffOnJobParams,job,ignoreProperties);
        job.setContractExpireTime(staffOnJobParams.getContractEndTime());
        return staffOnJobMapper.updateById(job);
    }
    //删除入职
@@ -120,10 +117,38 @@
        return staffContractMapper.delete(Wrappers.<StaffContract>lambdaQuery().in(StaffContract::getStaffOnJobId, ids));
    }
    // ç»­ç­¾åˆåŒ
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int renewContract(Long id, StaffContract staffContract) {
        // åˆ¤æ–­å¯¹è±¡æ˜¯å¦å­˜åœ¨
        StaffOnJob job = staffOnJobMapper.selectById(id);
        if (job == null){
            throw new BaseException("该员工不存在,无法更新!!!");
        }
        // å¢žåŠ åˆåŒ
        StaffContract newStaffContract = new StaffContract();
        newStaffContract.setStaffOnJobId(id);
        newStaffContract.setContractTerm(staffContract.getContractTerm());
        newStaffContract.setContractStartTime(staffContract.getContractStartTime());
        newStaffContract.setContractEndTime(staffContract.getContractEndTime());
        staffContractMapper.insert(newStaffContract);
        // æ›´æ–°å‘˜å·¥åˆåŒè¿‡æœŸæ—¶é—´
        job.setContractExpireTime(staffContract.getContractEndTime());
        staffOnJobMapper.updateById(job);
        return 0;
    }
    //在职员工详情
    @Override
    public StaffOnJobDto staffOnJobDetail(Long id) {
        StaffOnJob staffOnJob  = staffOnJobMapper.selectById(id);
        if (staffOnJob == null) {
            throw new IllegalArgumentException("该员工不存在");
        }
        StaffOnJobDto staffOnJobDto = new StaffOnJobDto();
        BeanUtils.copyProperties(staffOnJob, staffOnJobDto);
        // æŸ¥è¯¢å²—位名称
@@ -133,6 +158,7 @@
        // æŸ¥è¯¢åˆåŒä¿¡æ¯
        StaffContract contract = staffContractMapper.selectOne(Wrappers.<StaffContract>lambdaQuery()
                .eq(StaffContract::getStaffOnJobId, staffOnJob.getId())
                .last("limit 1")
                .orderByDesc(StaffContract::getId));
        if (contract != null){
            staffOnJobDto.setContractTerm(contract.getContractTerm());
@@ -151,8 +177,8 @@
    }
    @Override
    public List<StaffJoinLeaveRecord> staffOnJobList() {
        return staffJoinLeaveRecordMapper.staffOnJobList();
    public List<StaffOnJobDto> staffOnJobList(StaffOnJob staffOnJob) {
        return staffOnJobMapper.staffOnJobList(staffOnJob);
    }
    @Override
src/main/resources/mapper/basic/ProductModelMapper.xml
@@ -13,7 +13,6 @@
        <result column="tenant_id" property="tenantId" />
        <result column="product_name" property="productName" />
        <result column="product_id" property="productId" />
        <result column="product_code" property="productCode" />
    </resultMap>
    <select id="listPageProductModel" resultType="com.ruoyi.basic.pojo.ProductModel">
        select pm.*,p.product_name
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
@@ -361,6 +361,7 @@
    <select id="listPageByProductProduction" resultType="com.ruoyi.procurementrecord.dto.ProcurementPageDto">
        select
        t1.*,
        t1.inbound_num as inboundNum0,
        t2.model as specification_model  ,
        t2.unit,
        t3.product_name as product_category
src/main/resources/mapper/staff/StaffJoinLeaveRecordMapper.xml
ÎļþÒÑɾ³ý
src/main/resources/mapper/staff/StaffLeaveMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
<?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="com.ruoyi.staff.mapper.StaffLeaveMapper">
    <select id="staffLeaveListPage" resultType="com.ruoyi.staff.dto.StaffLeaveDto">
        SELECT
        staff_leave.*,
        soj.staff_name as staffName,
        soj.staff_state as staffState,
        soj.staff_no as staffNo,
        soj.sex as sex,
        soj.native_place as nativePlace,
        soj.adress as adress,
        soj.first_study as firstStudy,
        soj.profession as profession,
        soj.identity_card as identityCard,
        soj.age as age,
        soj.phone as phone,
        soj.emergency_contact as emergencyContact,
        soj.emergency_contact_phone as emergencyContactPhone,
        sp.post_name as postName,
        sd.dept_name as deptName
        FROM staff_leave
        LEFT JOIN
        staff_on_job soj ON soj.id = staff_leave.staff_on_job_id
        LEFT JOIN
        sys_post sp ON sp.post_id = soj.sys_post_id
        LEFT JOIN
        sys_dept sd ON sd.dept_id = soj.sys_dept_id
        where 1=1
        <if test="c.staffName != null and c.staffName != '' ">
            AND soj.staff_name LIKE CONCAT('%',#{c.staffName},'%')
        </if>
    </select>
    <select id="staffLeaveList" resultType="com.ruoyi.staff.dto.StaffLeaveDto">
        SELECT
        staff_leave.*,
        soj.staff_name as staffName,
        soj.staff_state as staffState,
        soj.staff_no as staffNo,
        soj.sex as sex,
        soj.native_place as nativePlace,
        soj.adress as adress,
        soj.first_study as firstStudy,
        soj.profession as profession,
        soj.identity_card as identityCard,
        soj.age as age,
        soj.phone as phone,
        soj.emergency_contact as emergencyContact,
        soj.emergency_contact_phone as emergencyContactPhone,
        sp.post_name as postName,
        sd.dept_name as deptName
        FROM staff_leave
        LEFT JOIN
        staff_on_job soj ON soj.id = staff_leave.staff_on_job_id
        LEFT JOIN
        sys_post sp ON sp.post_id = soj.sys_post_id
        LEFT JOIN
        sys_dept sd ON sd.dept_id = soj.sys_dept_id
        where 1=1
        <if test="c.staffName != null and c.staffName != '' ">
            AND soj.staff_name LIKE CONCAT('%',#{c.staffName},'%')
        </if>
    </select>
</mapper>
src/main/resources/mapper/staff/StaffOnJobMapper.xml
@@ -4,10 +4,13 @@
    <select id="staffOnJobListPage" resultType="com.ruoyi.staff.dto.StaffOnJobDto">
        SELECT
        staff_on_job.*,
        sp.post_name as postName
        sp.post_name as postName,
        sd.dept_name as deptName
        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
        where 1=1
        <if test="staffOnJob.staffState != null">
        AND staff_state = #{staffOnJob.staffState}
@@ -25,10 +28,13 @@
    <select id="staffOnJobList" resultType="com.ruoyi.staff.dto.StaffOnJobDto">
        SELECT
        staff_on_job.*,
        sp.post_name as postName
        sp.post_name as postName,
        sd.dept_name as deptName
        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
        where 1=1
        <if test="staffOnJob.staffState != null">
            AND staff_state = #{staffOnJob.staffState}
src/main/resources/mapper/system/SysUserMapper.xml
@@ -88,7 +88,7 @@
        <if test="params.endTime != null and params.endTime != ''"><!-- ç»“束时间检索 -->
            AND date_format(u.create_time,'%Y%m%d') &lt;= date_format(#{params.endTime},'%Y%m%d')
        </if>
        <if test="params.deptId != null">
        <if test="deptId != null">
            AND u.user_id IN
            (
            SELECT user_id FROM sys_user_dept WHERE dept_id = #{deptId}