gongchunyi
17 小时以前 2d1e904f3049218474318cb1e2fe5c3a3869cfb0
Merge remote-tracking branch 'origin/dev_New' into dev_New
已添加23个文件
已修改27个文件
1655 ■■■■ 文件已修改
src/main/java/com/ruoyi/ScheduleTask.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductOrderDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/mapper/SysDeptMapper.java 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java 144 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/controller/SafeAccidentController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/controller/SafeTrainingController.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/controller/SafeTrainingDetailsController.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/controller/SafeTrainingFileController.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/dto/SafeTrainingDetailsDto.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/dto/SafeTrainingDto.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/mapper/SafeTrainingDetailsMapper.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/mapper/SafeTrainingFileMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/mapper/SafeTrainingMapper.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/pojo/SafeTraining.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/pojo/SafeTrainingDetails.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/pojo/SafeTrainingFile.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/SafeTrainingDetailsService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/SafeTrainingFileService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/SafeTrainingService.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/impl/SafeHiddenServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/impl/SafeTrainingDetailsServiceImpl.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/impl/SafeTrainingFileServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/impl/SafeTrainingServiceImpl.java 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesLedgerProductDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/ShippingInfoMapper.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedger.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/ShippingInfoService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/CommonFileServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/InvoiceLedgerServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductOrderMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/safe/SafeAccidentMapper.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/safe/SafeTrainingDetailsMapper.xml 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/safe/SafeTrainingFileMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/safe/SafeTrainingMapper.xml 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesLedgerMapper.xml 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/ShippingInfoMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/safe-training-details.docx 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/safe-training.docx 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/ScheduleTask.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
package com.ruoyi;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.project.system.domain.SysNotice;
import com.ruoyi.project.system.mapper.SysNoticeMapper;
import com.ruoyi.safe.mapper.SafeTrainingMapper;
import com.ruoyi.safe.pojo.SafeTraining;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
@Component
//定时任务汇总
public class ScheduleTask {
    @Autowired
    private SafeTrainingMapper safeTrainingMapper;
    @Autowired
    private SysNoticeMapper noticeMapper;
    //定时任务(15分钟执行一次--判断培训计划数据,状态做变更)
    @Scheduled(cron = "0 0/15 * * * ?")
    public void testScheduleTask() {
        List<SafeTraining> safeTrainings = safeTrainingMapper.selectList(Wrappers.<SafeTraining>lambdaQuery().ne(SafeTraining::getState, 2));
        if (safeTrainings.size() > 0) {
            for (SafeTraining safeTraining : safeTrainings) {
                //根据时间判断培训状态
                String trainingDate = safeTraining.getTrainingDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                LocalDateTime openingTime = LocalDateTime.parse((trainingDate + safeTraining.getOpeningTime()), DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"));
                LocalDateTime endTime = LocalDateTime.parse((trainingDate + safeTraining.getEndTime()), DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"));
                if (LocalDateTime.now().isBefore(openingTime)) {
                    //未开始
                    safeTraining.setState(0);
                } else if (LocalDateTime.now().isAfter(endTime)) {
                    //已结束
                    safeTraining.setState(2);
                } else {
                    //进行中
                    safeTraining.setState(1);
                }
                safeTrainingMapper.updateById(safeTraining);
            }
        }
    }
    //已读数据做一个定时任务(每月1号1点清理一次上个月已读数据)
    @Scheduled(cron = "0 0 1 1 * ?")
    public void cleanReadData() {
        noticeMapper.delete(Wrappers.<SysNotice>lambdaQuery()
                .eq(SysNotice::getStatus,"1")
                .lt(SysNotice::getCreateTime, LocalDateTime.now()));
    }
}
src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
@@ -1,6 +1,7 @@
package com.ruoyi.approve.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -12,20 +13,21 @@
import com.ruoyi.approve.service.IApproveNodeService;
import com.ruoyi.approve.vo.ApproveProcessVO;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.device.mapper.DeviceRepairMapper;
import com.ruoyi.device.pojo.DeviceRepair;
import com.ruoyi.other.service.impl.TempFileServiceImpl;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.project.system.service.ISysNoticeService;
import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.sales.mapper.CommonFileMapper;
import com.ruoyi.sales.mapper.SalesQuotationMapper;
import com.ruoyi.sales.mapper.SalesQuotationProductMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.purchase.service.impl.PurchaseLedgerServiceImpl;
import com.ruoyi.sales.mapper.*;
import com.ruoyi.sales.pojo.CommonFile;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.pojo.SalesQuotation;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
@@ -42,7 +44,7 @@
import java.util.List;
@Service
@RequiredArgsConstructor
//@RequiredArgsConstructor
public class ApproveNodeServiceImpl extends ServiceImpl<ApproveNodeMapper, ApproveNode> implements IApproveNodeService {
    @Autowired
@@ -73,7 +75,13 @@
    @Autowired
    private CommonFileServiceImpl commonFileService;
    @Autowired
    private StockUtils stockUtils;
    @Autowired
    private SalesLedgerProductMapper salesLedgerProductMapper;
    @Autowired
    private PurchaseLedgerServiceImpl purchaseLedgerServiceImpl;
    public ApproveProcess getApproveById(String id) {
@@ -186,6 +194,17 @@
                if (status.equals(2)) {
                    // åŒæ„
                    purchaseLedger.setApprovalStatus(3);
                    List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(new QueryWrapper<SalesLedgerProduct>()
                            .lambda().eq(SalesLedgerProduct::getSalesLedgerId, purchaseLedger.getId()).eq(SalesLedgerProduct::getType, 2));
                    for (SalesLedgerProduct salesLedgerProduct : salesLedgerProducts) {
                        // è´¨æ£€
                        if (salesLedgerProduct.getIsChecked()) {
                            purchaseLedgerServiceImpl.addQualityInspect(purchaseLedger, salesLedgerProduct);
                        }else {
                            //直接入库
                            stockUtils.addStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockQualifiedRecordTypeEnum.PURCHASE_STOCK_IN.getCode(), purchaseLedger.getId());
                        }
                    }
                } else if (status.equals(3)) {
                    // æ‹’绝
                    purchaseLedger.setApprovalStatus(4);
@@ -222,7 +241,7 @@
                if(status.equals(2)){
                    shippingInfo.setStatus("审核通过");
                }else if(status.equals(3)){
                    shippingInfo.setType("审核拒绝");
                    shippingInfo.setStatus("审核拒绝");
                }else if(status.equals(1)){
                    shippingInfo.setStatus("审核中");
                }
@@ -248,10 +267,17 @@
                        .eq(ApproveProcess::getApproveId, approveNode.getApproveProcessId())).get(0);
                if (approveProcess.getApproveUserIds().split(",").length > nodeOrder){
                    String id = approveProcess.getApproveUserIds().split(",")[nodeOrder];
                    sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                            approveNode.getApproveProcessId()+"流程编号的审批需要您审核!!!!!",
                            Arrays.asList(Long.valueOf(id)),
                            "/collaborativeApproval/approvalProcess?approveType="+approveProcess.getApproveType()+"&approveId="+approveNode.getApproveProcessId());
                    if (approveProcess.getApproveType()==8){
                        sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                                approveProcess.getApproveId() + "流程编号的审批需要您审核!!!!!",
                                Arrays.asList(Long.valueOf(id)),
                                "/safeProduction/safeWorkApproval?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
                    }else {
                        sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                                approveProcess.getApproveId() + "流程编号的审批需要您审核!!!!!",
                                Arrays.asList(Long.valueOf(id)),
                                "/collaborativeApproval/approvalProcess?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
                    }
                }
                break;
            case 2:
@@ -294,7 +320,9 @@
            case 6:
                return "报价审批";
            case 7:
                return "出库审批";
                return "发货审批";
            case 8:
                return "危险作业审批";
        }
        return null;
    }
src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
@@ -51,22 +51,30 @@
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
//@RequiredArgsConstructor
public class ApproveProcessServiceImpl extends ServiceImpl<ApproveProcessMapper, ApproveProcess> implements IApproveProcessService {
    private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
    private final StringRedisTemplate redisTemplate;
    private final DailyRedisCounter dailyRedisCounter;
    private final SysDeptMapper sysDeptMapper;
    private final IApproveNodeService approveNodeService;
    private final SysUserMapper sysUserMapper;
    private final ApproveProcessMapper approveProcessMapper;
    private final TempFileServiceImpl tempFileService;
    private final CommonFileMapper commonFileMapper;
    private final CommonFileServiceImpl commonFileService;
    private final ISysNoticeService sysNoticeService;
    @Autowired
    private  StringRedisTemplate redisTemplate;
    @Autowired
    private  DailyRedisCounter dailyRedisCounter;
    @Autowired
    private  SysDeptMapper sysDeptMapper;
    @Autowired
    private  IApproveNodeService approveNodeService;
    @Autowired
    private  SysUserMapper sysUserMapper;
    @Autowired
    private  ApproveProcessMapper approveProcessMapper;
    @Autowired
    private  TempFileServiceImpl tempFileService;
    @Autowired
    private  CommonFileMapper commonFileMapper;
    @Autowired
    private  CommonFileServiceImpl commonFileService;
    @Autowired
    private  ISysNoticeService sysNoticeService;
    @Override
    public void addApprove(ApproveProcessVO approveProcessVO) throws Exception {
@@ -126,10 +134,17 @@
        tempFileService.migrateTempFilesToFormal(approveProcess.getId(), approveProcessVO.getTempFileIds(), FileNameType.ApproveProcess.getValue());
        /*消息通知*/
        String id = approveProcessVO.getApproveUserIds().split(",")[0];
        sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcessVO.getApproveType()),
                approveID + "流程编号的审批需要您审核!!!!!",
                Arrays.asList(Long.valueOf(id)),
                "/collaborativeApproval/approvalProcess?approveType=" + approveProcessVO.getApproveType() + "&approveId=" + approveID);
        if (approveProcess.getApproveType()==8){
            sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                    approveProcess.getApproveId() + "流程编号的审批需要您审核!!!!!",
                    Arrays.asList(Long.valueOf(id)),
                    "/safeProduction/safeWorkApproval?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
        }else {
            sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                    approveProcess.getApproveId() + "流程编号的审批需要您审核!!!!!",
                    Arrays.asList(Long.valueOf(id)),
                    "/collaborativeApproval/approvalProcess?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
        }
    }
    @Override
@@ -239,7 +254,8 @@
        return one;
    }
    private final ApproveNodeMapper approveNodeMapper;
    @Autowired
    private ApproveNodeMapper approveNodeMapper;
    // æŠ¥ä»·å®¡æ‰¹ç¼–辑审核人
    public void updateApproveUser(ApproveGetAndUpdateVo approveGetAndUpdateVo) {
@@ -276,10 +292,17 @@
        approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(), approveProcess.getApproveId(), approveProcess.getTenantId());
        /*消息通知*/
        String id = approveProcess.getApproveUserIds().split(",")[0];
        sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                approveProcess.getApproveId() + "流程编号的审批需要您审核!!!!!",
                Arrays.asList(Long.valueOf(id)),
                "/collaborativeApproval/approvalProcess?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
        if (approveProcess.getApproveType()==8){
            sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                    approveProcess.getApproveId() + "流程编号的审批需要您审核!!!!!",
                    Arrays.asList(Long.valueOf(id)),
                    "/safeProduction/safeWorkApproval?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
        }else {
            sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                    approveProcess.getApproveId() + "流程编号的审批需要您审核!!!!!",
                    Arrays.asList(Long.valueOf(id)),
                    "/collaborativeApproval/approvalProcess?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
        }
    }
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -1,6 +1,7 @@
package com.ruoyi.procurementrecord.utils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper;
import com.ruoyi.stock.dto.StockInRecordDto;
@@ -101,14 +102,16 @@
        StockInRecord one = stockInRecordService.getOne(new QueryWrapper<StockInRecord>()
                .lambda().eq(StockInRecord::getRecordId, recordId)
                .eq(StockInRecord::getRecordType, recordType));
        stockInRecordService.batchDelete(Collections.singletonList(one.getId()));
        if (ObjectUtils.isNotEmpty(one)) {
            stockInRecordService.batchDelete(Collections.singletonList(one.getId()));
        }
    }
    public void deleteStockOutRecord(Long recordId, String recordType) {
        StockOutRecord one = stockOutRecordService.getOne(new QueryWrapper<StockOutRecord>()
                .lambda().eq(StockOutRecord::getRecordId, recordId)
                .eq(StockOutRecord::getRecordType, recordType));
        stockOutRecordService.batchDelete(Collections.singletonList(one.getId()));
        if (ObjectUtils.isNotEmpty(one)) {
            stockOutRecordService.batchDelete(Collections.singletonList(one.getId()));
        }
    }
}
src/main/java/com/ruoyi/production/dto/ProductOrderDto.java
@@ -43,4 +43,7 @@
    @ApiModelProperty(value = "BOM编号")
    @Excel(name = "BOM编号")
    private String bomNo;
    @ApiModelProperty(value = "交期偏差")
    private Integer deliveryDaysDiff;
}
src/main/java/com/ruoyi/project/system/mapper/SysDeptMapper.java
@@ -1,19 +1,22 @@
package com.ruoyi.project.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.project.system.domain.SysDept;
/**
 * éƒ¨é—¨ç®¡ç† æ•°æ®å±‚
 *
 *
 * @author ruoyi
 */
@Mapper
public interface SysDeptMapper
{
    /**
     * æŸ¥è¯¢éƒ¨é—¨ç®¡ç†æ•°æ®
     *
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return éƒ¨é—¨ä¿¡æ¯é›†åˆ
     */
@@ -21,7 +24,7 @@
    /**
     * æ ¹æ®è§’色ID查询部门树信息
     *
     *
     * @param roleId è§’色ID
     * @param deptCheckStrictly éƒ¨é—¨æ ‘选择项是否关联显示
     * @return é€‰ä¸­éƒ¨é—¨åˆ—表
@@ -30,7 +33,7 @@
    /**
     * æ ¹æ®éƒ¨é—¨ID查询信息
     *
     *
     * @param deptId éƒ¨é—¨ID
     * @return éƒ¨é—¨ä¿¡æ¯
     */
@@ -38,7 +41,7 @@
    /**
     * æ ¹æ®ID查询所有子部门
     *
     *
     * @param deptId éƒ¨é—¨ID
     * @return éƒ¨é—¨åˆ—表
     */
@@ -46,7 +49,7 @@
    /**
     * æ ¹æ®ID查询所有子部门(正常状态)
     *
     *
     * @param deptId éƒ¨é—¨ID
     * @return å­éƒ¨é—¨æ•°
     */
@@ -54,7 +57,7 @@
    /**
     * æ˜¯å¦å­˜åœ¨å­èŠ‚ç‚¹
     *
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
@@ -62,7 +65,7 @@
    /**
     * æŸ¥è¯¢éƒ¨é—¨æ˜¯å¦å­˜åœ¨ç”¨æˆ·
     *
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
@@ -70,7 +73,7 @@
    /**
     * æ ¡éªŒéƒ¨é—¨åç§°æ˜¯å¦å”¯ä¸€
     *
     *
     * @param deptName éƒ¨é—¨åç§°
     * @param parentId çˆ¶éƒ¨é—¨ID
     * @return ç»“æžœ
@@ -79,7 +82,7 @@
    /**
     * æ–°å¢žéƒ¨é—¨ä¿¡æ¯
     *
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return ç»“æžœ
     */
@@ -87,7 +90,7 @@
    /**
     * ä¿®æ”¹éƒ¨é—¨ä¿¡æ¯
     *
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return ç»“æžœ
     */
@@ -95,14 +98,14 @@
    /**
     * ä¿®æ”¹æ‰€åœ¨éƒ¨é—¨æ­£å¸¸çŠ¶æ€
     *
     *
     * @param deptIds éƒ¨é—¨ID组
     */
    public void updateDeptStatusNormal(Long[] deptIds);
    /**
     * ä¿®æ”¹å­å…ƒç´ å…³ç³»
     *
     *
     * @param depts å­å…ƒç´ 
     * @return ç»“æžœ
     */
@@ -110,7 +113,7 @@
    /**
     * åˆ é™¤éƒ¨é—¨ç®¡ç†ä¿¡æ¯
     *
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
@@ -1,5 +1,6 @@
package com.ruoyi.project.system.service.impl;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -22,6 +23,7 @@
import com.ruoyi.project.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.ruoyi.project.system.domain.SysNotice;
import com.ruoyi.project.system.mapper.SysNoticeMapper;
@@ -210,4 +212,5 @@
        sysNotice.setTenantId(tenantId);
        return sysNotice;
    }
}
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -55,6 +55,7 @@
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
@@ -84,52 +85,71 @@
 * @date 2025-05-09
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class PurchaseLedgerServiceImpl extends ServiceImpl<PurchaseLedgerMapper, PurchaseLedger> implements IPurchaseLedgerService {
    private final AccountExpenseService accountExpenseService;
    private final PurchaseLedgerMapper purchaseLedgerMapper;
    @Autowired
    private  AccountExpenseService accountExpenseService;
    @Autowired
    private  PurchaseLedgerMapper purchaseLedgerMapper;
    private final SalesLedgerMapper salesLedgerMapper;
    private final SalesLedgerProductMapper salesLedgerProductMapper;
    @Autowired
    private  SalesLedgerMapper salesLedgerMapper;
    @Autowired
    private  SalesLedgerProductMapper salesLedgerProductMapper;
    private final SysUserMapper userMapper;
    @Autowired
    private  SysUserMapper userMapper;
    private final TempFileMapper tempFileMapper;
    @Autowired
    private  TempFileMapper tempFileMapper;
    private final CommonFileMapper commonFileMapper;
    @Autowired
    private  CommonFileMapper commonFileMapper;
    private final SupplierManageMapper supplierManageMapper;
    @Autowired
    private  SupplierManageMapper supplierManageMapper;
    private final ProductMapper productMapper;
    @Autowired
    private  ProductMapper productMapper;
    private final ProductModelMapper productModelMapper;
    @Autowired
    private  ProductModelMapper productModelMapper;
    private final SysUserMapper sysUserMapper;
    @Autowired
    private  SysUserMapper sysUserMapper;
    private final TicketRegistrationMapper ticketRegistrationMapper;
    @Autowired
    private  TicketRegistrationMapper ticketRegistrationMapper;
    private final ProductRecordMapper productRecordMapper;
    @Autowired
    private  ProductRecordMapper productRecordMapper;
    private final PaymentRegistrationMapper paymentRegistrationMapper;
    private final InvoiceRegistrationProductMapper invoiceRegistrationProductMapper;
    private final StringRedisTemplate redisTemplate;
    private final QualityInspectMapper qualityInspectMapper;
    private final CommonFileServiceImpl commonFileService;
    private final QualityTestStandardBindingMapper qualityTestStandardBindingMapper;
    private final QualityTestStandardParamMapper qualityTestStandardParamMapper;
    private final QualityTestStandardMapper qualityTestStandardMapper;
    private final QualityInspectParamMapper qualityInspectParamMapper;
    private final ApproveProcessServiceImpl approveProcessService;
    private final ProcurementRecordMapper procurementRecordStorageMapper;
    private final PurchaseLedgerTemplateMapper purchaseLedgerTemplateMapper;
    private final SalesLedgerProductTemplateMapper salesLedgerProductTemplateMapper;
    @Autowired
    private  PaymentRegistrationMapper paymentRegistrationMapper;
    @Autowired
    private  InvoiceRegistrationProductMapper invoiceRegistrationProductMapper;
    @Autowired
    private  StringRedisTemplate redisTemplate;
    @Autowired
    private  QualityInspectMapper qualityInspectMapper;
    @Autowired
    private  CommonFileServiceImpl commonFileService;
    @Autowired
    private  QualityTestStandardBindingMapper qualityTestStandardBindingMapper;
    @Autowired
    private  QualityTestStandardParamMapper qualityTestStandardParamMapper;
    @Autowired
    private  QualityTestStandardMapper qualityTestStandardMapper;
    @Autowired
    private  QualityInspectParamMapper qualityInspectParamMapper;
    @Autowired
    private  ApproveProcessServiceImpl approveProcessService;
    @Autowired
    private  ProcurementRecordMapper procurementRecordStorageMapper;
    @Autowired
    private  PurchaseLedgerTemplateMapper purchaseLedgerTemplateMapper;
    @Autowired
    private  SalesLedgerProductTemplateMapper salesLedgerProductTemplateMapper;
    @Value("${file.upload-dir}")
    private String uploadDir;
@@ -205,7 +225,8 @@
        return 1;
    }
    private void addQualityInspect(PurchaseLedger purchaseLedger, SalesLedgerProduct saleProduct) {
    public void addQualityInspect(PurchaseLedger purchaseLedger, SalesLedgerProduct saleProduct) {
        QualityInspect qualityInspect = new QualityInspect();
        qualityInspect.setInspectType(0);
        qualityInspect.setSupplier(purchaseLedger.getSupplierName());
@@ -400,6 +421,12 @@
        if (ids == null || ids.length == 0) {
           throw new BaseException("请选中至少一条数据");
        }
        for (Long id : ids) {
            PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(id);
            if (purchaseLedger.getApprovalStatus().equals(3)) {
                throw new BaseException(purchaseLedger.getPurchaseContractNumber()+"已经审批通过,不允许删除");
            }
        }
        // æ‰¹é‡åˆ é™¤å…³è”的采购入库记录
        LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductQueryWrapper = new LambdaQueryWrapper<>();
        salesLedgerProductQueryWrapper.in(SalesLedgerProduct::getSalesLedgerId, ids)
src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java
@@ -29,6 +29,7 @@
     */
    @PostMapping("/add")
    public AjaxResult add(@RequestBody QualityUnqualified qualityUnqualified) {
        qualityUnqualified.setInspectState(0);
        return AjaxResult.success(qualityUnqualifiedService.save(qualityUnqualified));
    }
src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
@@ -63,82 +63,84 @@
    public int deal(QualityUnqualified qualityUnqualified) {
        QualityUnqualified unqualified = qualityUnqualifiedMapper.selectById(qualityUnqualified.getId());
        QualityInspect qualityInspect = qualityInspectService.getById(unqualified.getInspectId());
        switch (qualityUnqualified.getDealResult()) {
            case "返修":
            case "返工":
                //判断质检表是否有相关的报工id,如果有报工id,那么返工需要重新创建生产订单重新生产
                if (ObjectUtils.isNotNull(qualityInspect.getProductMainId())) {
                    //返工需要重新创建生产订单重新生产
                    ProductOrder productOrder = productionProductMainMapper.getOrderByMainId(qualityInspect.getProductMainId());
                    ProductOrder order = new ProductOrder();
                    BeanUtils.copyProperties(productOrder, order);
                    order.setId(null);
                    order.setQuantity(unqualified.getQuantity());
                    order.setCompleteQuantity(BigDecimal.ZERO);
                    order.setStartTime(null);
                    order.setEndTime(null);
                    productOrderService.save(order);
                    //新增生产订单下的工艺路线主表
                    ProductProcessRoute productProcessRoute = productProcessRouteMapper.selectList(Wrappers.<ProductProcessRoute>lambdaQuery().eq(ProductProcessRoute::getProductOrderId, productOrder.getId()).orderByDesc(ProductProcessRoute::getId)).get(0);
                    ProductProcessRoute newProcessRoute = new ProductProcessRoute();
                    BeanUtils.copyProperties(productProcessRoute, newProcessRoute);
                    newProcessRoute.setId(null);
                    newProcessRoute.setProductOrderId(order.getId());
                    productProcessRouteMapper.insert(newProcessRoute);
                    //新增生产订单下的工艺路线子表
                    List<ProductProcessRouteItem> processRouteItems = productProcessRouteItemMapper.selectList(new QueryWrapper<ProductProcessRouteItem>().lambda().eq(ProductProcessRouteItem::getProductRouteId, productProcessRoute.getId()));
                    // ç”Ÿæˆå½“前日期的前缀:年月日
                    String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
                    for (ProductProcessRouteItem processRouteItem : processRouteItems) {
                        ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
                        BeanUtils.copyProperties(processRouteItem, productProcessRouteItem);
                        productProcessRouteItem.setId(null);
                        productProcessRouteItem.setProductRouteId(newProcessRoute.getId());
                        int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
                        if (insert > 0) {
                            // æŸ¥è¯¢ä»Šæ—¥å·²å­˜åœ¨çš„æœ€å¤§å·¥å•号
                            QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
                            queryWrapper.likeRight("work_order_no", datePrefix)
                                    .orderByDesc("work_order_no")
                                    .last("LIMIT 1");
                            ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
                            int sequenceNumber = 1; // é»˜è®¤åºå·
                            if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                                String lastNo = lastWorkOrder.getWorkOrderNo().toString();
                                if (lastNo.startsWith(datePrefix)) {
                                    String seqStr = lastNo.substring(datePrefix.length());
                                    try {
                                        sequenceNumber = Integer.parseInt(seqStr) + 1;
                                    } catch (NumberFormatException e) {
                                        sequenceNumber = 1;
        if (ObjectUtils.isNotNull(qualityInspect) && qualityInspect.getInspectType()!=0) {
            switch (qualityUnqualified.getDealResult()) {
                case "返修":
                case "返工":
                    //判断质检表是否有相关的报工id,如果有报工id,那么返工需要重新创建生产订单重新生产
                    if (ObjectUtils.isNotNull(qualityInspect.getProductMainId())) {
                        //返工需要重新创建生产订单重新生产
                        ProductOrder productOrder = productionProductMainMapper.getOrderByMainId(qualityInspect.getProductMainId());
                        ProductOrder order = new ProductOrder();
                        BeanUtils.copyProperties(productOrder, order);
                        order.setId(null);
                        order.setQuantity(unqualified.getQuantity());
                        order.setCompleteQuantity(BigDecimal.ZERO);
                        order.setStartTime(null);
                        order.setEndTime(null);
                        productOrderService.save(order);
                        //新增生产订单下的工艺路线主表
                        ProductProcessRoute productProcessRoute = productProcessRouteMapper.selectList(Wrappers.<ProductProcessRoute>lambdaQuery().eq(ProductProcessRoute::getProductOrderId, productOrder.getId()).orderByDesc(ProductProcessRoute::getId)).get(0);
                        ProductProcessRoute newProcessRoute = new ProductProcessRoute();
                        BeanUtils.copyProperties(productProcessRoute, newProcessRoute);
                        newProcessRoute.setId(null);
                        newProcessRoute.setProductOrderId(order.getId());
                        productProcessRouteMapper.insert(newProcessRoute);
                        //新增生产订单下的工艺路线子表
                        List<ProductProcessRouteItem> processRouteItems = productProcessRouteItemMapper.selectList(new QueryWrapper<ProductProcessRouteItem>().lambda().eq(ProductProcessRouteItem::getProductRouteId, productProcessRoute.getId()));
                        // ç”Ÿæˆå½“前日期的前缀:年月日
                        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
                        for (ProductProcessRouteItem processRouteItem : processRouteItems) {
                            ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
                            BeanUtils.copyProperties(processRouteItem, productProcessRouteItem);
                            productProcessRouteItem.setId(null);
                            productProcessRouteItem.setProductRouteId(newProcessRoute.getId());
                            int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
                            if (insert > 0) {
                                // æŸ¥è¯¢ä»Šæ—¥å·²å­˜åœ¨çš„æœ€å¤§å·¥å•号
                                QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
                                queryWrapper.likeRight("work_order_no", datePrefix)
                                        .orderByDesc("work_order_no")
                                        .last("LIMIT 1");
                                ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
                                int sequenceNumber = 1; // é»˜è®¤åºå·
                                if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                                    String lastNo = lastWorkOrder.getWorkOrderNo().toString();
                                    if (lastNo.startsWith(datePrefix)) {
                                        String seqStr = lastNo.substring(datePrefix.length());
                                        try {
                                            sequenceNumber = Integer.parseInt(seqStr) + 1;
                                        } catch (NumberFormatException e) {
                                            sequenceNumber = 1;
                                        }
                                    }
                                }
                                // ç”Ÿæˆå®Œæ•´çš„工单号
                                String workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
                                ProductWorkOrder productWorkOrder = new ProductWorkOrder();
                                productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
                                productWorkOrder.setProductOrderId(order.getId());
                                productWorkOrder.setPlanQuantity(order.getQuantity());
                                productWorkOrder.setWorkOrderNo(workOrderNoStr);
                                productWorkOrder.setStatus(1);
                                productWorkOrderMapper.insert(productWorkOrder);
                            }
                            // ç”Ÿæˆå®Œæ•´çš„工单号
                            String workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
                            ProductWorkOrder productWorkOrder = new ProductWorkOrder();
                            productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
                            productWorkOrder.setProductOrderId(order.getId());
                            productWorkOrder.setPlanQuantity(order.getQuantity());
                            productWorkOrder.setWorkOrderNo(workOrderNoStr);
                            productWorkOrder.setStatus(1);
                            productWorkOrderMapper.insert(productWorkOrder);
                        }
                    }
                }
                break;
            case "报废":
                //调用不合格库存接口 å…¥ä¸åˆæ ¼åº“
                stockUtils.addUnStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockUnQualifiedRecordTypeEnum.DEFECTIVE_SCRAP.getCode(),unqualified.getId());
                break;
            case "让步放行":
                //调用提交合格的接口
                stockUtils.addStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockQualifiedRecordTypeEnum.DEFECTIVE_PASS.getCode(),unqualified.getId());
                qualityInspect.setCheckResult("合格");
                qualityInspectService.submit(qualityInspect);
                break;
            default:
                break;
                    break;
                case "报废":
                    //调用不合格库存接口 å…¥ä¸åˆæ ¼åº“
                    stockUtils.addUnStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockUnQualifiedRecordTypeEnum.DEFECTIVE_SCRAP.getCode(), unqualified.getId());
                    break;
                case "让步放行":
                    //调用提交合格的接口
                    stockUtils.addStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockQualifiedRecordTypeEnum.DEFECTIVE_PASS.getCode(), unqualified.getId());
                    qualityInspect.setCheckResult("合格");
                    qualityInspectService.submit(qualityInspect);
                    break;
                default:
                    break;
            }
        }
        qualityUnqualified.setInspectState(1);//已处理
        return qualityUnqualifiedMapper.updateById(qualityUnqualified);
src/main/java/com/ruoyi/safe/controller/SafeAccidentController.java
@@ -48,7 +48,7 @@
    @ApiOperation("删除事故上报记录")
    @DeleteMapping("/{ids}")
    public R delSafeCertification(@RequestBody List<Integer> ids) {
    public R delSafeAccident(@RequestBody List<Integer> ids) {
        return R.ok(safeAccidentService.removeBatchByIds(ids));
    }
src/main/java/com/ruoyi/safe/controller/SafeTrainingController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
package com.ruoyi.safe.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.pojo.SafeAccident;
import com.ruoyi.safe.pojo.SafeTraining;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.ruoyi.safe.service.SafeAccidentService;
import com.ruoyi.safe.service.SafeTrainingDetailsService;
import com.ruoyi.safe.service.SafeTrainingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核 å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:06
 */
@RestController
@RequestMapping("/safeTraining")
@Api(tags = "安全生产--安全培训考核")
public class SafeTrainingController {
    @Autowired
    private SafeTrainingService safeTrainingService;
    @Autowired
    private SafeTrainingDetailsService safeTrainingDetailsService;
    @GetMapping("/page")
    @ApiOperation("分页查询")
    public R page(Page page, SafeTrainingDto safeTrainingDto) {
        return R.ok(safeTrainingService.pageSafeTraining(page, safeTrainingDto));
    }
    @ApiOperation("新增/编辑安全培训考核")
    @PostMapping()
    public R addOrUpdate(@RequestBody SafeTraining safeTraining) {
        return R.ok(safeTrainingService.addOrUpdate(safeTraining));
    }
    @ApiOperation("签到")
    @PostMapping ("/sign")
    public R sign(@RequestBody SafeTrainingDetails safeTrainingDetails) {
        return R.ok(safeTrainingDetailsService.save(safeTrainingDetails));
    }
    @ApiOperation("结果明细查询")
    @GetMapping ("/getSafeTraining")
    public R getSafeTraining(Long id) {
        return R.ok(safeTrainingService.getSafeTraining(id));
    }
    @ApiOperation("结果明细保存")
    @PostMapping ("/saveSafeTraining")
    public R saveSafeTraining(@RequestBody SafeTrainingDto safeTrainingDto) {
        return R.ok(safeTrainingService.saveSafeTraining(safeTrainingDto));
    }
    @ApiOperation("删除安全培训考核")
    @DeleteMapping("/{ids}")
    public R delSafeTraining(@RequestBody List<Integer> ids) {
        return R.ok(safeTrainingService.delSafeTraining(ids));
    }
    @ApiOperation("导出")
    @PostMapping ("/export")
    public void export(HttpServletResponse response, @RequestBody SafeTraining safeTraining) {
        safeTrainingService.export(response,safeTraining.getId());
    }
}
src/main/java/com/ruoyi/safe/controller/SafeTrainingDetailsController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
package com.ruoyi.safe.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.pojo.SafeTraining;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.ruoyi.safe.service.SafeTrainingDetailsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--记录详情 å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:15
 */
@RestController
@RequestMapping("/safeTrainingDetails")
@Api(tags = "安全生产--安全培训考核--记录详情")
public class SafeTrainingDetailsController {
    @Autowired
    private SafeTrainingDetailsService safeTrainingDetailsService;
    @GetMapping("/page")
    @ApiOperation("分页查询")
    public R page(Page page, SafeTrainingDetails safeTrainingDetails) {
        return R.ok(safeTrainingDetailsService.pageDetails(page, safeTrainingDetails));
    }
    @ApiOperation("导出")
    @PostMapping("/export")
    public void export(HttpServletResponse response, @RequestBody SafeTrainingDetails safeTrainingDetails) {
        safeTrainingDetailsService.export(response,safeTrainingDetails.getUserId());
    }
}
src/main/java/com/ruoyi/safe/controller/SafeTrainingFileController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
package com.ruoyi.safe.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.safe.pojo.SafeHiddenFile;
import com.ruoyi.safe.pojo.SafeTrainingFile;
import com.ruoyi.safe.service.SafeTrainingFileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--附件 å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:23
 */
@RestController
@RequestMapping("/safeTrainingFile")
@Api(tags = "安全生产--安全培训考核--附件")
public class SafeTrainingFileController {
    @Resource
    private SafeTrainingFileService safeTrainingFileService;
    /**
     * æ–°å¢ž
     * @param safeHiddenFile
     * @return
     */
    @PostMapping("/add")
    @ApiOperation("新增")
    public R add(@RequestBody SafeTrainingFile safeHiddenFile) {
        return R.ok(safeTrainingFileService.save(safeHiddenFile));
    }
    /**
     * åˆ é™¤
     * @param ids
     * @return
     */
    @DeleteMapping("/del")
    @ApiOperation("删除")
    public R delSafeHiddenFile(@RequestBody List<Integer> ids) {
        if(CollectionUtils.isEmpty(ids)){
            return R.fail("请选择至少一条数据");
        }
        //删除检验附件
        return R.ok(safeTrainingFileService.removeBatchByIds(ids));
    }
    /**
     *分页查询
     * @param page
     * @param safeTrainingFile
     * @return
     */
    @GetMapping("/listPage")
    @ApiOperation("分页查询")
    public R listPage(Page page, SafeTrainingFile safeTrainingFile) {
        return R.ok(safeTrainingFileService.page(page, Wrappers.<SafeTrainingFile>lambdaQuery().eq(SafeTrainingFile::getSafeTrainingId,safeTrainingFile.getSafeTrainingId())));
    }
}
src/main/java/com/ruoyi/safe/dto/SafeTrainingDetailsDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.ruoyi.safe.dto;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
public class SafeTrainingDetailsDto extends SafeTrainingDetails {
    @ApiModelProperty("培训人员编号")
    private String userName;
    @ApiModelProperty("培训人员名称")
    private String nickName;
    @ApiModelProperty("手机号码")
    private String phonenumber;
}
src/main/java/com/ruoyi/safe/dto/SafeTrainingDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.ruoyi.safe.dto;
import com.ruoyi.safe.pojo.SafeTraining;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.ruoyi.safe.pojo.SafeTrainingFile;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
public class SafeTrainingDto extends SafeTraining {
    @ApiModelProperty("报名人数")
    private Integer nums;
    @ApiModelProperty("评价人")
    private String assessmentUserName;
    @ApiModelProperty("附件集合")
    private List<SafeTrainingFile> safeTrainingFileList;
    @ApiModelProperty("培训记录人员详情集合")
    private List<SafeTrainingDetailsDto> safeTrainingDetailsDtoList;
}
src/main/java/com/ruoyi/safe/mapper/SafeTrainingDetailsMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package com.ruoyi.safe.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.dto.SafeTrainingDetailsDto;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--记录详情 Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:15
 */
@Mapper
public interface SafeTrainingDetailsMapper extends BaseMapper<SafeTrainingDetails> {
    List<SafeTrainingDetailsDto> getSafeTraining(@Param("id") Long id);
    IPage<SafeTrainingDetails> pageDetails(Page page, @Param("c") SafeTrainingDetails safeTrainingDetails);
}
src/main/java/com/ruoyi/safe/mapper/SafeTrainingFileMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.safe.mapper;
import com.ruoyi.safe.pojo.SafeTrainingFile;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--附件 Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:23
 */
@Mapper
public interface SafeTrainingFileMapper extends BaseMapper<SafeTrainingFile> {
}
src/main/java/com/ruoyi/safe/mapper/SafeTrainingMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.ruoyi.safe.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.pojo.SafeTraining;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核 Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:06
 */
@Mapper
public interface SafeTrainingMapper extends BaseMapper<SafeTraining> {
    IPage<SafeTrainingDto> pageSafeTraining(Page page, @Param("c") SafeTrainingDto safeTrainingDto);
    SafeTrainingDto getSafeTraining(@Param("id") Long id);
}
src/main/java/com/ruoyi/safe/pojo/SafeTraining.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,123 @@
package com.ruoyi.safe.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotBlank;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:06
 */
@Getter
@Setter
@TableName("safe_training")
@ApiModel(value = "SafeTraining对象", description = "安全生产--安全培训考核")
public class SafeTraining implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("课程编号")
    private String courseCode;
    @ApiModelProperty("培训目标")
    private String trainingObjectives;
    @ApiModelProperty("培训内容")
    private String trainingContent;
    @ApiModelProperty("培训方式")
    private String trainingMode;
    @ApiModelProperty("状态(0:未开始1:进行中;2:已结束)")
    private Integer state;
    @ApiModelProperty("参加对象")
    private String participants;
    @ApiModelProperty("培训地点")
    private String placeTraining;
    @ApiModelProperty("培训讲师")
    private String trainingLecturer;
    @ApiModelProperty("培训日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @NotBlank(message = "培训日期不能为空")
    private LocalDate trainingDate;
    @ApiModelProperty("开始时间(时分秒)")
    @NotBlank(message = "开始时间不能为空")
    private String openingTime;
    @ApiModelProperty("结束时间(时分秒)")
    @NotBlank(message = "结束时间不能为空")
    private String endTime;
    @ApiModelProperty("课题学分")
    private String projectCredits;
    @ApiModelProperty("课时")
    private Double classHour;
    @ApiModelProperty("考核方式")
    private String assessmentMethod;
    @ApiModelProperty("本次培训综合评价")
    private String comprehensiveAssessment;
    @ApiModelProperty("备注")
    private String remarks;
    @ApiModelProperty("评价人id")
    private Integer assessmentUserId;
    @ApiModelProperty("评价时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate assessmentDate;
    @ApiModelProperty("培训摘要")
    private String trainingAbstract;
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @TableField(fill = FieldFill.INSERT)
    private Integer tenantId;
}
src/main/java/com/ruoyi/safe/pojo/SafeTrainingDetails.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,95 @@
package com.ruoyi.safe.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotBlank;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--记录详情
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:15
 */
@Getter
@Setter
@TableName("safe_training_details")
@ApiModel(value = "SafeTrainingDetails对象", description = "安全生产--安全培训考核--记录详情")
public class SafeTrainingDetails implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("用户表格(user)主键")
    @NotBlank(message = "用户id不能为空")
    private Long userId;
    @ApiModelProperty("关联安全培训考核id")
    private Integer safeTrainingId;
    @ApiModelProperty("考核结果")
    private String examinationResults;
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @TableField(fill = FieldFill.INSERT)
    private Integer tenantId;
    @ApiModelProperty("培训日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @TableField(exist = false)
    private LocalDate trainingDate;
    @ApiModelProperty("课程编号")
    @TableField(exist = false)
    private String courseCode;
    @ApiModelProperty("培训内容")
    @TableField(exist = false)
    private String trainingContent;
    @ApiModelProperty("培训课时")
    @TableField(exist = false)
    private Double classHour;
    @ApiModelProperty("课题学分")
    @TableField(exist = false)
    private String projectCredits;
    @ApiModelProperty("备注")
    @TableField(exist = false)
    private String remarks;
}
src/main/java/com/ruoyi/safe/pojo/SafeTrainingFile.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,57 @@
package com.ruoyi.safe.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--附件
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:23
 */
@Getter
@Setter
@TableName("safe_training_file")
@ApiModel(value = "SafeTrainingFile对象", description = "安全生产--安全培训考核--附件")
public class SafeTrainingFile implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("关联安全培训考核id")
    private Integer safeTrainingId;
    private String name;
    private String url;
    private Object fileSize;
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @TableField(fill = FieldFill.INSERT)
    private Integer tenantId;
}
src/main/java/com/ruoyi/safe/service/SafeTrainingDetailsService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.safe.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.servlet.http.HttpServletResponse;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--记录详情 æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:15
 */
public interface SafeTrainingDetailsService extends IService<SafeTrainingDetails> {
    IPage<SafeTrainingDetails> pageDetails(Page page, SafeTrainingDetails safeTrainingDetails);
    void export(HttpServletResponse response, Long userId);
}
src/main/java/com/ruoyi/safe/service/SafeTrainingFileService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.safe.service;
import com.ruoyi.safe.pojo.SafeTrainingFile;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--附件 æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:23
 */
public interface SafeTrainingFileService extends IService<SafeTrainingFile> {
}
src/main/java/com/ruoyi/safe/service/SafeTrainingService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
package com.ruoyi.safe.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.pojo.SafeTraining;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核 æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:06
 */
public interface SafeTrainingService extends IService<SafeTraining> {
    IPage<SafeTrainingDto> pageSafeTraining(Page page, SafeTrainingDto safeTrainingDto);
    int addOrUpdate(SafeTraining safeTraining);
    SafeTrainingDto getSafeTraining(Long id);
    int saveSafeTraining(SafeTrainingDto safeTrainingDto);
    int delSafeTraining(List<Integer> ids);
    void export(HttpServletResponse response, Long id);
}
src/main/java/com/ruoyi/safe/service/impl/SafeHiddenServiceImpl.java
@@ -47,7 +47,7 @@
    @Override
    public int add(SafeHidden safeHidden) {
        safeHiddenMapper.insert(safeHidden);
        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
        String no = "YH" + String.format("%s%03d", datePrefix, safeHidden.getId());
        safeHidden.setHiddenCode(no);
        safeHiddenMapper.updateById(safeHidden);
src/main/java/com/ruoyi/safe/service/impl/SafeTrainingDetailsServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
package com.ruoyi.safe.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.ruoyi.common.utils.HackLoopTableRenderPolicy;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.safe.dto.SafeTrainingDetailsDto;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.ruoyi.safe.mapper.SafeTrainingDetailsMapper;
import com.ruoyi.safe.service.SafeTrainingDetailsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--记录详情 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:15
 */
@Service
public class SafeTrainingDetailsServiceImpl extends ServiceImpl<SafeTrainingDetailsMapper, SafeTrainingDetails> implements SafeTrainingDetailsService {
    @Autowired
    private SafeTrainingDetailsMapper safeTrainingDetailsMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Override
    public IPage<SafeTrainingDetails> pageDetails(Page page, SafeTrainingDetails safeTrainingDetails) {
        return safeTrainingDetailsMapper.pageDetails(page, safeTrainingDetails);
    }
    @Override
    public void export(HttpServletResponse response, Long userId) {
        SafeTrainingDetails safeTrainingDetails = new SafeTrainingDetails();
        safeTrainingDetails.setUserId(userId);
        SysUser sysUser = sysUserMapper.selectUserById(userId);
        List<SafeTrainingDetails> safeTrainingDetailsList = safeTrainingDetailsMapper.pageDetails(new Page(1, -1), safeTrainingDetails).getRecords();
        InputStream inputStream = this.getClass().getResourceAsStream("/static/safe-training-details.docx");
        Configure configure = Configure.builder()
                .bind("safeTrainingDetailsList", new HackLoopTableRenderPolicy())
                .build();
        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
                new HashMap<String, Object>() {{
                    put("user", sysUser);
                    put("safeTrainingDetailsList", safeTrainingDetailsList);
                }});
        try {
            response.setContentType("application/msword");
            String fileName = URLEncoder.encode(
                    "培训与考核记录", "UTF-8");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-disposition",
                    "attachment;filename=" + fileName + ".docx");
            OutputStream os = response.getOutputStream();
            template.write(os);
            os.flush();
            os.close();
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出失败");
        }
    }
}
src/main/java/com/ruoyi/safe/service/impl/SafeTrainingFileServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.safe.service.impl;
import com.ruoyi.safe.pojo.SafeTrainingFile;
import com.ruoyi.safe.mapper.SafeTrainingFileMapper;
import com.ruoyi.safe.service.SafeTrainingFileService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--附件 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:23
 */
@Service
public class SafeTrainingFileServiceImpl extends ServiceImpl<SafeTrainingFileMapper, SafeTrainingFile> implements SafeTrainingFileService {
}
src/main/java/com/ruoyi/safe/service/impl/SafeTrainingServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,179 @@
package com.ruoyi.safe.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.ruoyi.common.utils.HackLoopTableRenderPolicy;
import com.ruoyi.production.pojo.ProductOrder;
import com.ruoyi.production.pojo.ProductWorkOrder;
import com.ruoyi.project.system.domain.SysNotice;
import com.ruoyi.safe.dto.SafeTrainingDetailsDto;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.mapper.SafeTrainingDetailsMapper;
import com.ruoyi.safe.mapper.SafeTrainingFileMapper;
import com.ruoyi.safe.pojo.SafeTraining;
import com.ruoyi.safe.mapper.SafeTrainingMapper;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.ruoyi.safe.pojo.SafeTrainingFile;
import com.ruoyi.safe.service.SafeTrainingService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:06
 */
@Service
public class SafeTrainingServiceImpl extends ServiceImpl<SafeTrainingMapper, SafeTraining> implements SafeTrainingService {
    @Autowired
    private SafeTrainingMapper safeTrainingMapper;
    @Autowired
    private SafeTrainingFileMapper safeTrainingFileMapper;
    @Autowired
    private SafeTrainingDetailsMapper safeTrainingDetailsMapper;
    @Override
    public IPage<SafeTrainingDto> pageSafeTraining(Page page, SafeTrainingDto safeTrainingDto) {
        return safeTrainingMapper.pageSafeTraining(page, safeTrainingDto);
    }
    @Override
    public int addOrUpdate(SafeTraining safeTraining) {
        if (ObjectUtils.isNull(safeTraining.getId())) {
            String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
            // æŸ¥è¯¢ä»Šæ—¥å·²å­˜åœ¨çš„æœ€å¤§è¯¾ç¨‹ç¼–号
            QueryWrapper<SafeTraining> queryWrapper = new QueryWrapper<>();
            queryWrapper.likeRight("course_code", datePrefix)
                    .orderByDesc("course_code")
                    .last("LIMIT 1");
            SafeTraining lastSafeTraining = safeTrainingMapper.selectOne(queryWrapper);
            int sequenceNumber = 1; // é»˜è®¤åºå·
            if (lastSafeTraining != null && lastSafeTraining.getCourseCode() != null) {
                String lastNo = lastSafeTraining.getCourseCode().toString();
                if (lastNo.startsWith(datePrefix)) {
                    String seqStr = lastNo.substring(datePrefix.length());
                    try {
                        sequenceNumber = Integer.parseInt(seqStr) + 1;
                    } catch (NumberFormatException e) {
                        sequenceNumber = 1;
                    }
                }
            }
            // ç”Ÿæˆå®Œæ•´çš„课程编号
            String no = "KC-" + String.format("%s%03d", datePrefix, sequenceNumber);
            safeTraining.setCourseCode(no);
        }
        //根据时间判断培训状态
        String trainingDate = safeTraining.getTrainingDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDateTime openingTime = LocalDateTime.parse((trainingDate + safeTraining.getOpeningTime()), DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"));
        LocalDateTime endTime = LocalDateTime.parse((trainingDate + safeTraining.getEndTime()), DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"));
        if (LocalDateTime.now().isBefore(openingTime)) {
            //未开始
            safeTraining.setState(0);
        } else if (LocalDateTime.now().isAfter(endTime)) {
            //已结束
            safeTraining.setState(2);
        } else {
            //进行中
            safeTraining.setState(1);
        }
        //新增或更新
        saveOrUpdate(safeTraining);
        return 0;
    }
    @Override
    public SafeTrainingDto getSafeTraining(Long id) {
        //主表数据
        SafeTrainingDto safeTrainingDto = safeTrainingMapper.getSafeTraining(id);
        //附件
        List<SafeTrainingFile> safeTrainingFiles = safeTrainingFileMapper.selectList(Wrappers.<SafeTrainingFile>lambdaQuery().eq(SafeTrainingFile::getSafeTrainingId, id));
        safeTrainingDto.setSafeTrainingFileList(safeTrainingFiles);
        //培训记录详情
        List<SafeTrainingDetailsDto> safeTrainingDetailsDto = safeTrainingDetailsMapper.getSafeTraining(id);
        safeTrainingDto.setSafeTrainingDetailsDtoList(safeTrainingDetailsDto);
        return safeTrainingDto;
    }
    @Override
    public int saveSafeTraining(SafeTrainingDto safeTrainingDto) {
        //更新主表
        safeTrainingMapper.updateById(safeTrainingDto);
        //更新培训记录详情
        safeTrainingDto.getSafeTrainingDetailsDtoList().forEach(safeTrainingDetailsDto -> {
            safeTrainingDetailsMapper.updateById(safeTrainingDetailsDto);
        });
        return 0;
    }
    @Override
    public int delSafeTraining(List<Integer> ids) {
        //删除主表
        safeTrainingMapper.deleteBatchIds(ids);
        //删除附件
        safeTrainingFileMapper.delete(Wrappers.<SafeTrainingFile>lambdaQuery().in(SafeTrainingFile::getSafeTrainingId, ids));
        //删除培训记录
        safeTrainingDetailsMapper.delete(Wrappers.<SafeTrainingDetails>lambdaQuery().in(SafeTrainingDetails::getSafeTrainingId, ids));
        return 0;
    }
    @Override
    public void export(HttpServletResponse response, Long id) {
        SafeTrainingDto safeTrainingDto = safeTrainingMapper.getSafeTraining(id);
        List<SafeTrainingDetailsDto> safeTrainingDetailsDtoList = safeTrainingDetailsMapper.getSafeTraining(id);
        InputStream inputStream = this.getClass().getResourceAsStream("/static/safe-training.docx");
        Configure configure = Configure.builder()
                .bind("safeTrainingDetailsDtoList", new HackLoopTableRenderPolicy())
                .build();
        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
                new HashMap<String, Object>() {{
                    put("safeTrainingDto", safeTrainingDto);
                    put("safeTrainingDetailsDtoList", safeTrainingDetailsDtoList);
                }});
        try {
            response.setContentType("application/msword");
            String fileName = URLEncoder.encode(
                    safeTrainingDto.getCourseCode() + "培训与考核计划", "UTF-8");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-disposition",
                    "attachment;filename=" + fileName + ".docx");
            OutputStream os = response.getOutputStream();
            template.write(os);
            os.flush();
            os.close();
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出失败");
        }
    }
}
src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java
@@ -64,7 +64,7 @@
    @GetMapping("/listPage")
    @ApiOperation("发货信息列表")
    public AjaxResult listPage(Page page, ShippingInfo req) {
        IPage<ShippingInfo> listPage = shippingInfoService.listPage(page,req);
        IPage<ShippingInfoDto> listPage = shippingInfoService.listPage(page,req);
        return AjaxResult.success(listPage);
    }
@@ -96,8 +96,6 @@
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "发货信息管理", businessType = BusinessType.UPDATE)
    public AjaxResult deductStock(@RequestBody ShippingInfoDto req) throws IOException {
        return shippingInfoService.deductStock( req) ? AjaxResult.success() : AjaxResult.error();
    }
src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
@@ -54,4 +54,7 @@
    @ApiModelProperty(value = "付款方式")
    private String paymentMethod;
    @ApiModelProperty(value = "交货日期")
    private LocalDate deliveryDate;
}
src/main/java/com/ruoyi/sales/dto/SalesLedgerProductDto.java
@@ -55,4 +55,6 @@
     */
    private Long supplierId;
    private Integer approvalStatus;
}
src/main/java/com/ruoyi/sales/mapper/ShippingInfoMapper.java
@@ -3,6 +3,7 @@
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.sales.dto.ShippingInfoDto;
import com.ruoyi.sales.pojo.ShippingInfo;
import org.apache.ibatis.annotations.Param;
@@ -13,7 +14,7 @@
 * @date : 2025/10/22 9:32
 */
public interface ShippingInfoMapper extends BaseMapper<ShippingInfo> {
    IPage<ShippingInfo> listPage(Page page,@Param("req") ShippingInfo req);
    IPage<ShippingInfoDto> listPage(Page page, @Param("req") ShippingInfo req);
    List<ShippingInfo> listAll();
}
src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
@@ -130,5 +130,14 @@
    @TableField(exist = false)
    @ApiModelProperty(value = "生产状态")
    private String productionStatus = "未开始";
    //交货日期
    @ApiModelProperty(value = "交货日期")
    @TableField(value = "delivery_date")
    private LocalDate deliveryDate;
    @TableField(exist = false)
    @ApiModelProperty(value = "交货天数差")
    private Integer deliveryDaysDiff;
}
src/main/java/com/ruoyi/sales/service/ShippingInfoService.java
@@ -14,7 +14,7 @@
 * @date : 2025/10/22 9:33
 */
public interface ShippingInfoService extends IService<ShippingInfo>{
    IPage<ShippingInfo> listPage(Page page, ShippingInfo req);
    IPage<ShippingInfoDto> listPage(Page page, ShippingInfo req);
    boolean deductStock(ShippingInfoDto req) throws IOException;
src/main/java/com/ruoyi/sales/service/impl/CommonFileServiceImpl.java
@@ -40,6 +40,11 @@
    @Value("${file.upload-dir}")
    private String uploadDir;
    public List<CommonFile> getFileListByBusinessId(Long businessId,Integer type) {
        return commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>().eq(CommonFile::getCommonId, businessId)
                .eq(CommonFile::getType, type));
    }
    public void deleteByBusinessId(Long businessId,Integer type) {
        commonFileMapper.delete(new LambdaQueryWrapper<CommonFile>().eq(CommonFile::getCommonId, businessId)
                .eq(CommonFile::getType, type));
src/main/java/com/ruoyi/sales/service/impl/InvoiceLedgerServiceImpl.java
@@ -326,6 +326,14 @@
        if(ObjectUtils.isEmpty(invoiceRegistrationProductDto)){
            throw new RuntimeException("产品开票台账查找失败");
        }
        List<InvoiceRegistrationProduct> invoiceRegistrationProducts = invoiceRegistrationProductMapper.selectList(new LambdaQueryWrapper<InvoiceRegistrationProduct>()
                .eq(InvoiceRegistrationProduct::getSalesLedgerProductId, invoiceRegistrationProductDto.getSalesLedgerProductId()));
        if(CollectionUtils.isNotEmpty(invoiceRegistrationProducts)){
            invoiceRegistrationProductDto.setNoInvoiceNum(invoiceRegistrationProductDto.getQuantity()
                    .subtract(invoiceRegistrationProducts.stream().map(InvoiceRegistrationProduct::getInvoiceNum).reduce(BigDecimal.ZERO, BigDecimal::add)));
            invoiceRegistrationProductDto.setNoInvoiceAmount(invoiceRegistrationProductDto.getTaxInclusiveTotalPrice()
                    .subtract(invoiceRegistrationProducts.stream().map(InvoiceRegistrationProduct::getInvoiceAmount).reduce(BigDecimal.ZERO, BigDecimal::add)));
        }
        // æŸ¥è¯¢é™„ä»¶
        QueryWrapper<InvoiceLedgerFile> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("invoice_ledger_id", invoiceRegistrationProductDto.getInvoiceLedgerId());
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
@@ -49,9 +49,11 @@
    private ApproveProcessServiceImpl approveProcessService;
    @Override
    public IPage<ShippingInfo> listPage(Page page, ShippingInfo req) {
        IPage<ShippingInfo> listPage = shippingInfoMapper.listPage(page, req);
    public IPage<ShippingInfoDto> listPage(Page page, ShippingInfo req) {
        IPage<ShippingInfoDto> listPage = shippingInfoMapper.listPage(page, req);
        listPage.getRecords().forEach(item ->{
            item.setCommonFileList(commonFileService.getFileListByBusinessId(item.getId(), FileNameType.SHIP.getValue()));
        });
        return listPage;
    }
@@ -61,14 +63,16 @@
        if (byId == null) {
            throw new RuntimeException("发货信息不存在");
        }
        //扣减库存
        if(!"已发货".equals(byId.getStatus())){
            SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(byId.getSalesLedgerProductId());
            stockUtils.substractStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId());
        }
        byId.setExpressNumber(req.getExpressNumber());
        byId.setExpressCompany(req.getExpressCompany());
        byId.setStatus("已发货");
        byId.setShippingCarNumber(req.getShippingCarNumber());
        boolean update = this.updateById(req);
        //扣减库存
        SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(req.getSalesLedgerProductId());
        stockUtils.substractStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId());
        boolean update = this.updateById(byId);
        // è¿ç§»æ–‡ä»¶
        if(CollectionUtils.isNotEmpty(req.getTempFileIds())){
            tempFileService.migrateTempFilesToFormal(req.getId(), req.getTempFileIds(), FileNameType.SHIP.getValue());
src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
@@ -69,8 +69,10 @@
        // æ›´æ–°å¯¹åº”用户状态为停用
        // æ ¹æ®å‘˜å·¥ç¼–号查询用户
        SysUser sysUser = sysUserMapper.selectUserByUserName(staffOnJob.getStaffNo());
        sysUser.setStatus("1");
        sysUserMapper.updateUser(sysUser);
        if (sysUser != null) {
            sysUser.setStatus("1");
            sysUserMapper.updateUser(sysUser);
        }
        // æ›´æ–°ç¦»èŒçŠ¶æ€ä¸ºç¦»èŒ
        staffOnJob.setStaffState(0);
src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
@@ -90,7 +90,7 @@
            throw new BaseException("编号为"+staffOnJobParams.getStaffNo()+"的员工不存在,无法更新!!!");
        }
        String[] ignoreProperties = {"id"};//排除id属性
        String[] ignoreProperties = {"id"};//排除更新属性
        // èŽ·å–æœ€æ–°åˆåŒæ•°æ®ï¼Œå¹¶ä¸”æ›´æ–°
        StaffContract contract = staffContractMapper.selectOne(Wrappers.<StaffContract>lambdaQuery()
@@ -103,9 +103,8 @@
        }
        // æ›´æ–°å‘˜å·¥æ•°æ®
        BeanUtils.copyProperties(staffOnJobParams,job,ignoreProperties);
        job.setContractExpireTime(staffOnJobParams.getContractEndTime());
        return staffOnJobMapper.updateById(job);
        staffOnJobParams.setContractExpireTime(staffOnJobParams.getContractEndTime());
        return staffOnJobMapper.updateById(staffOnJobParams);
    }
    //删除入职
src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -21,7 +21,8 @@
        slp.specification_model,
        ppr.process_route_code,
        pb.bom_no,
        ROUND(po.complete_quantity / po.quantity * 100, 2) AS completionStatus
        ROUND(po.complete_quantity / po.quantity * 100, 2) AS completionStatus,
        DATEDIFF(sl.delivery_date, CURDATE()) AS delivery_days_diff
        from product_order po
        left join sales_ledger sl on po.sales_ledger_id = sl.id
        left join sales_ledger_product slp on po.product_model_id = slp.id
src/main/resources/mapper/safe/SafeAccidentMapper.xml
@@ -27,7 +27,7 @@
    </resultMap>
    <select id="pageSafeAccident" resultType="com.ruoyi.safe.pojo.SafeAccident">
        select sa.*,
               su.nick_name createUserName,
               su.nick_name createUserName
        from safe_accident sa
        left join sys_user su on sa.create_user = su.user_id
        where 1=1
@@ -35,13 +35,13 @@
            and sa.accident_code like concat('%', #{c.accidentCode}, '%')
        </if>
        <if test="c.accidentName != null and c.accidentName != ''">
            and sa.accident_name like concat('%', #{accidentName}, '%')
            and sa.accident_name like concat('%', #{c.accidentName}, '%')
        </if>
        <if test="c.accidentType != null and c.accidentType != ''">
            and sa.accident_type like concat('%', #{accidentType}, '%')
            and sa.accident_type like concat('%', #{c.accidentType}, '%')
        </if>
        <if test="c.accidentGrade != null and c.accidentGrade != ''">
            and sa.accident_grade like concat('%', #{accidentGrade}, '%')
            and sa.accident_grade like concat('%', #{c.accidentGrade}, '%')
        </if>
    </select>
src/main/resources/mapper/safe/SafeTrainingDetailsMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
<?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.safe.mapper.SafeTrainingDetailsMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.safe.pojo.SafeTrainingDetails">
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="safe_training_id" property="safeTrainingId"/>
        <result column="examination_results" property="examinationResults"/>
        <result column="create_time" property="createTime"/>
        <result column="create_user" property="createUser"/>
        <result column="update_time" property="updateTime"/>
        <result column="update_user" property="updateUser"/>
        <result column="tenant_id" property="tenantId"/>
    </resultMap>
    <select id="getSafeTraining" resultType="com.ruoyi.safe.dto.SafeTrainingDetailsDto">
        select std.*,
               su.user_name,
               su.nick_name,
               su.phonenumber
        from safe_training_details std
                 left join sys_user su on std.user_id = su.user_id
        where std.safe_training_id = #{id}
    </select>
    <select id="pageDetails" resultType="com.ruoyi.safe.pojo.SafeTrainingDetails">
        select std.*,
               st.*
        from safe_training_details std
                 left join safe_training st on std.safe_training_id = st.id
        where std.user_id = #{c.userId}
        <if test="c.trainingDate != null">
            and st.training_date = #{c.trainingDate}
        </if>
    </select>
</mapper>
src/main/resources/mapper/safe/SafeTrainingFileMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
<?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.safe.mapper.SafeTrainingFileMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.safe.pojo.SafeTrainingFile">
        <id column="id" property="id" />
        <result column="safe_training_id" property="safeTrainingId" />
        <result column="name" property="name" />
        <result column="url" property="url" />
        <result column="file_size" property="fileSize" />
        <result column="create_time" property="createTime" />
        <result column="create_user" property="createUser" />
        <result column="update_time" property="updateTime" />
        <result column="update_user" property="updateUser" />
        <result column="tenant_id" property="tenantId" />
    </resultMap>
</mapper>
src/main/resources/mapper/safe/SafeTrainingMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
<?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.safe.mapper.SafeTrainingMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.safe.pojo.SafeTraining">
        <id column="id" property="id" />
        <result column="course_code" property="courseCode" />
        <result column="training_objectives" property="trainingObjectives" />
        <result column="training_content" property="trainingContent" />
        <result column="training_mode" property="trainingMode" />
        <result column="state" property="state" />
        <result column="participants" property="participants" />
        <result column="place_training" property="placeTraining" />
        <result column="training_lecturer" property="trainingLecturer" />
        <result column="training_date" property="trainingDate" />
        <result column="opening_time" property="openingTime" />
        <result column="end_time" property="endTime" />
        <result column="project_credits" property="projectCredits" />
        <result column="class_hour" property="classHour" />
        <result column="assessment_method" property="assessmentMethod" />
        <result column="comprehensive_assessment" property="comprehensiveAssessment" />
        <result column="remarks" property="remarks" />
        <result column="assessment_user_id" property="assessmentUserId" />
        <result column="assessment_date" property="assessmentDate" />
        <result column="training_abstract" property="trainingAbstract" />
        <result column="create_time" property="createTime" />
        <result column="create_user" property="createUser" />
        <result column="update_time" property="updateTime" />
        <result column="update_user" property="updateUser" />
        <result column="tenant_id" property="tenantId" />
    </resultMap>
    <select id="pageSafeTraining" resultType="com.ruoyi.safe.dto.SafeTrainingDto">
        select st.*,
               su.nick_name assessmentUserName,
                count(std.id) nums
        from safe_training st
        left join safe_training_details std on std.safe_training_id = st.id
        left join sys_user su on st.assessment_user_id = su.user_id
        where 1=1
        <if test="c.placeTraining != null and c.placeTraining != ''">
            and st.place_training like concat('%', #{c.placeTraining}, '%')
        </if>
        <if test="c.trainingDate != null and c.trainingDate != ''">
            and st.training_date = #{c.trainingDate}
        </if>
        <if test="c.state != null and c.state != ''">
            and st.state like concat('%', #{c.state}, '%')
        </if>
    </select>
    <select id="getSafeTraining" resultType="com.ruoyi.safe.dto.SafeTrainingDto">
         select st.*,
                su.nick_name assessmentUserName
         from safe_training st
                  left join sys_user su on st.assessment_user_id = su.user_id
         where st.id=#{id}
    </select>
</mapper>
src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -15,24 +15,25 @@
    <select id="selectSalesLedgerList" resultType="com.ruoyi.sales.pojo.SalesLedger">
        SELECT
            T1.id,
            T1.sales_contract_no,
            T1.customer_contract_no,
            T1.project_name,
            T1.entry_date,
            T1.salesman,
            T1.customer_id,
            T1.customer_name,
            T1.entry_person,
            T1.remarks,
            T1.attachment_materials,
            T1.tenant_id,
            T1.contract_amount,
            T1.execution_date,
            T2.nick_name AS entry_person_name,
            T1.payment_method
        T1.id,
        T1.sales_contract_no,
        T1.customer_contract_no,
        T1.project_name,
        T1.entry_date,
        T1.salesman,
        T1.customer_id,
        T1.customer_name,
        T1.entry_person,
        T1.remarks,
        T1.attachment_materials,
        T1.tenant_id,
        T1.contract_amount,
        T1.execution_date,
        T2.nick_name AS entry_person_name,
        T1.payment_method,
        DATEDIFF(T1.delivery_date, CURDATE()) AS delivery_days_diff
        FROM
            sales_ledger T1
        sales_ledger T1
        LEFT JOIN sys_user T2 ON T1.entry_person = T2.user_id
        <where>
            <if test="salesLedgerDto.customerName != null and salesLedgerDto.customerName != '' ">
@@ -59,7 +60,9 @@
        T1.contract_amount as noInvoiceAmountTotal,
        T1.execution_date,
        T2.nick_name AS entry_person_name,
        T1.payment_method
        T1.payment_method,
        T1.delivery_date,
        DATEDIFF(T1.delivery_date, CURDATE()) AS delivery_days_diff
        FROM
        sales_ledger T1
        LEFT JOIN sys_user T2 ON T1.entry_person = T2.user_id
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -81,6 +81,9 @@
            <if test="req.purchaseContractNumber != null and req.purchaseContractNumber != '' ">
                AND sl.purchase_contract_number like concat('%',#{req.purchaseContractNumber},'%')
            </if>
            <if test="req.approvalStatus != null and req.approvalStatus != ''">
                and sl.approval_status = #{req.approvalStatus}
            </if>
            <if test="req.customerContractNo != null and req.customerContractNo != '' ">
                AND sl.customer_contract_no like concat('%',#{req.customerContractNo},'%')
            </if>
src/main/resources/mapper/sales/ShippingInfoMapper.xml
@@ -2,7 +2,7 @@
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.sales.mapper.ShippingInfoMapper">
    <select id="listPage" resultType="com.ruoyi.sales.pojo.ShippingInfo">
    <select id="listPage" resultType="com.ruoyi.sales.dto.ShippingInfoDto">
        SELECT
        s.id,
        s.sales_ledger_id,
src/main/resources/static/safe-training-details.docx
Binary files differ
src/main/resources/static/safe-training.docx
Binary files differ