liyong
昨天 ba4af275c3b8d073f863be7b12e43974b3ef14a2
Merge branch 'master' of http://114.132.189.42:9002/r/product-inventory-management-after into pim_ly
已修改27个文件
已添加21个文件
1654 ■■■■■ 文件已修改
pom.xml 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/controller/ApproveNodeController.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/controller/ApproveProcessController.java 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/mapper/ApproveLogMapper.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/mapper/ApproveNodeMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/mapper/ApproveProcessMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/pojo/ApproveLog.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/pojo/ApproveNode.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/pojo/ApproveProcess.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/IApproveNodeService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/IApproveProcessService.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/utils/DailyRedisCounter.java 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/utils/StartAndEndDateDto.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/vo/ApproveGetAndUpdateVo.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/vo/ApproveProcessVO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/SupplierServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/framework/security/service/TokenService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/other/service/impl/TempFileServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementManagementUpdateDto.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementPageDto.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementPageDtoCopy.java 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementRecordOutPageDto.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordOut.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordOutServiceImpl.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/controller/SysUserController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/controller/StaffOnJobController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/IStaffOnJobService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/approve/ApproveLogMapper.xml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/approve/ApproveNodeMapper.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/approve/ApproveProcessMapper.xml 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/purchase/ProductRecordMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/quality/QualityUnqualifiedMapper.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/system/SysDeptMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/system/SysUserMapper.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
src/main/java/com/ruoyi/approve/controller/ApproveNodeController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
package com.ruoyi.approve.controller;
import com.ruoyi.approve.pojo.ApproveNode;
import com.ruoyi.approve.service.IApproveNodeService;
import com.ruoyi.framework.web.domain.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/approveNode")
public class ApproveNodeController {
    @Autowired
    private IApproveNodeService approveNodeService;
    /**
     * æµç¨‹çŠ¶æ€è¯¦æƒ…
     * @param id æµç¨‹å®¡æ‰¹id approve_id
     * @return
     */
    @GetMapping("/details/{id}")
    public AjaxResult details(@PathVariable String id) {
        return AjaxResult.success(approveNodeService.details(id));
    }
    /**
     * å®¡æ‰¹èŠ‚ç‚¹
     * @param approveNode
     * @return
     */
    @PostMapping("/updateApproveNode")
    public AjaxResult updateApproveNode(@RequestBody ApproveNode approveNode) {
        approveNodeService.updateApproveNode(approveNode);
        return AjaxResult.success();
    }
    /**
     * åˆå§‹åŒ–审批节点
     * @param id
     * @return
     */
    @PostMapping("/init")
    public AjaxResult init(String id) {
        approveNodeService.initApproveNodes("",id,1L);
        return AjaxResult.success();
    }
}
src/main/java/com/ruoyi/approve/controller/ApproveProcessController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,112 @@
package com.ruoyi.approve.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.service.IApproveProcessService;
import com.ruoyi.approve.vo.ApproveGetAndUpdateVo;
import com.ruoyi.approve.vo.ApproveProcessVO;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.system.domain.SysDept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.text.ParseException;
import java.util.List;
@RestController
@RequestMapping("/approveProcess")
public class ApproveProcessController {
    @GetMapping("/test")
    public AjaxResult test() {
        System.out.println(1111);
        return AjaxResult.success("测试");
    }
    @Autowired
    private IApproveProcessService approveProcessService;
    /**、
     * èŽ·å–éƒ¨é—¨åˆ—è¡¨
     * @return
     */
    @GetMapping("/getDept")
    public AjaxResult getDept() {
        Long userId = SecurityUtils.getUserId();
        LoginUser user = SecurityUtils.getLoginUser();
        Long[] deptIds = SecurityUtils.getDeptId();
        List<SysDept> sysDeptList = approveProcessService.selectDeptListByDeptIds(deptIds);
        return AjaxResult.success(sysDeptList);
    }
    /**
     * æ·»åŠ å®¡æ‰¹
     * @param approveProcessVO
     * @return
     */
    @PostMapping("/add")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody ApproveProcessVO approveProcessVO) throws ParseException {
        if (approveProcessVO == null) {
            return AjaxResult.warn("参数不能为空");
        }
        approveProcessService.addApprove(approveProcessVO);
        return AjaxResult.success("添加成功");
    }
    /**
     * å®¡æ‰¹è¯¦æƒ…
     * @param approveGetAndUpdateVo
     * @return
     */
    @GetMapping("/get")
    public AjaxResult get(ApproveGetAndUpdateVo approveGetAndUpdateVo){
        if (approveGetAndUpdateVo.getId() == null || approveGetAndUpdateVo.getId().isEmpty()) {
            return AjaxResult.warn("参数不能为空");
        }
        return AjaxResult.success(approveProcessService.getApproveById(approveGetAndUpdateVo.getId()));
    }
    /**
     * æ›´æ–°å®¡æ‰¹
     * @param approveGetAndUpdateVo
     * @return
     */
    @PostMapping("/update")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(@RequestBody ApproveGetAndUpdateVo approveGetAndUpdateVo) {
        if (approveGetAndUpdateVo == null) {
            return AjaxResult.warn("参数不能为空");
        }
        approveProcessService.updateByApproveId(approveGetAndUpdateVo);
        return AjaxResult.success("操作成功");
    }
    /**
     * èŽ·å–å®¡æ‰¹åˆ—è¡¨
     * @return
     */
    @GetMapping("/list")
    public AjaxResult list(Page page, ApproveProcess approveProcess) {
        return AjaxResult.success(approveProcessService.listAll(page, approveProcess));
    }
    /**
     * åˆ é™¤å®¡æ‰¹
     * @param ids
     * @return
     */
    @DeleteMapping("/deleteIds")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult deleteIds(@RequestBody Long[] ids) {
        if (ids == null || ids.length == 0) {
            return AjaxResult.warn("参数不能为空");
        }
        approveProcessService.delApprove(ids);
        return AjaxResult.success("操作成功");
    }
}
src/main/java/com/ruoyi/approve/mapper/ApproveLogMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.approve.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.approve.pojo.ApproveLog;
import org.apache.ibatis.annotations.Mapper;
/**
* @author Administrator
* @description é’ˆå¯¹è¡¨ã€approve_log(审批日志表)】的数据库操作Mapper
* @createDate 2025-07-07 14:47:01
* @Entity com.ruoyi.approve.pojo.ApproveLog
*/
@Mapper
public interface ApproveLogMapper extends BaseMapper<ApproveLog> {
}
src/main/java/com/ruoyi/approve/mapper/ApproveNodeMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.approve.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.approve.pojo.ApproveNode;
/**
* @author Administrator
* @description é’ˆå¯¹è¡¨ã€approve_node(审批节点表)】的数据库操作Mapper
* @createDate 2025-07-08 16:50:15
* @Entity com.ruoyi.approve.pojo.ApproveNode
*/
public interface ApproveNodeMapper extends BaseMapper<ApproveNode> {
}
src/main/java/com/ruoyi/approve/mapper/ApproveProcessMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.approve.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.approve.pojo.ApproveProcess;
import org.apache.ibatis.annotations.Param;
/**
* @author Administrator
* @description é’ˆå¯¹è¡¨ã€approve_process(审批流程表)】的数据库操作Mapper
* @createDate 2025-07-08 16:44:05
* @Entity com.ruoyi.approve.pojo.ApproveProcess
*/
public interface ApproveProcessMapper extends BaseMapper<ApproveProcess> {
    IPage<ApproveProcess> listPage(Page page,@Param("req") ApproveProcess approveProcess);
}
src/main/java/com/ruoyi/approve/pojo/ApproveLog.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,57 @@
package com.ruoyi.approve.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
 * å®¡æ‰¹æ—¥å¿—表
 * @TableName approve_log
 */
@Data
@TableName("approve_log")
public class ApproveLog implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * å®¡æ‰¹id
     */
    private Long approveId;
    /**
     * å®¡æ‰¹èŠ‚ç‚¹é¡ºåº
     */
    private Integer approveNodeOrder;
    /**
     * å®¡æ‰¹äººid
     */
    private Long approveUser;
    /**
     * å®¡æ‰¹æ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date approveTime;
    /**
     * å®¡æ‰¹çŠ¶æ€
     */
    private Integer approveStatus;
    /**
     * å®¡æ‰¹å¤‡æ³¨
     */
    private String approveRemark;
}
src/main/java/com/ruoyi/approve/pojo/ApproveNode.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,116 @@
package com.ruoyi.approve.pojo;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
/**
 * å®¡æ‰¹èŠ‚ç‚¹è¡¨
 * @TableName approve_node
 */
@Data
@TableName("approve_node")
public class ApproveNode{
    /**
     *
     */
    private Long id;
    /**
     * å®¡æ‰¹ç¼–号
     */
    private String approveProcessId;
    /**
     * å®¡æ‰¹èŠ‚ç‚¹é¡ºåº
     */
    private Integer approveNodeOrder;
    /**
     * å®¡æ‰¹èŠ‚ç‚¹ç”¨æˆ·åå­—
     */
    private String approveNodeUser;
    /**
     * å®¡æ‰¹èŠ‚ç‚¹ç”¨æˆ·id
     */
    private Long approveNodeUserId;
    /**
     * å®¡æ‰¹èŠ‚ç‚¹æ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date approveNodeTime;
    /**
     * å®¡æ‰¹èŠ‚ç‚¹çŠ¶æ€:1同意,2拒绝,0尚未审核(默认为0)
     */
    private Integer approveNodeStatus;
    @TableField(exist = false)
    private Boolean isFirst;
    /**
     * æ˜¯å¦ä¸ºæœ€åŽä¸€æ­¥
     */
    @TableField(exist = false)
    private Boolean isLast;
    /**
     * æ˜¯å¦ä¸ºå½“前审核节点
     */
    @TableField(exist = false)
    private Boolean isShen = false;
    /**
     * ç§Ÿæˆ·id
     */
//    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    /**
     * åˆ é™¤æ ‡è®°:0正常,1删除
     */
    private Integer deleteFlag;
    /**
     * å…¥åº“用户id
     */
    private Long createUser;
    /**
     * å…¥åº“æ—¶é—´
     */
    private LocalDateTime createTime;
    /**
     * ä¿®æ”¹è€…
     */
    private Long updateUser;
    /**
     * ä¿®æ”¹æ—¶é—´
     */
    private LocalDateTime updateTime;
    /**
     * å®¡æ‰¹èŠ‚ç‚¹æ‹’ç»åŽŸå› 
     */
    private String approveNodeReason;
    /**
     * å®¡æ‰¹èŠ‚ç‚¹å¤‡æ³¨
     */
    private String approveNodeRemark;
    private static final long serialVersionUID = 1L;
}
src/main/java/com/ruoyi/approve/pojo/ApproveProcess.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,120 @@
package com.ruoyi.approve.pojo;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
/**
 * å®¡æ‰¹æµç¨‹è¡¨
 * @TableName approve_process
 */
@Data
@TableName("approve_process")
public class ApproveProcess{
    /**
     *
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * æµç¨‹ç¼–号
     */
    private String approveId;
    /**
     * ç”³è¯·äººid
     */
    private Long approveUser;
    /**
     * ç”³è¯·äººåç§°
     */
    private String approveUserName;
    /**
     * ç”³è¯·éƒ¨é—¨id
     */
    private Long approveDeptId;
    /**
     * ç”³è¯·éƒ¨é—¨åç§°
     */
    private String approveDeptName;
    /**
     * å®¡æ‰¹ç”¨æˆ·ids
     */
    private String approveUserIds;
    /**
     * å®¡æ‰¹ç”¨æˆ·åç§°
     */
    private String approveUserNames;
    /**
     * ç”³è¯·åŽŸå› 
     */
    private String approveReason;
    /**
     * å½“前审批用户ID
     */
    private Long approveUserCurrentId;
    /**
     * å½“前审批用户名称
     */
    private String approveUserCurrentName;
    /**
     * ç”³è¯·æ—¥æœŸ
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date approveTime;
    /**
     * å®¡æ‰¹å®Œæˆæ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date approveOverTime;
    /**
     * å®¡æ‰¹çŠ¶æ€ï¼š0待审核,1审核中,2审核完成 3审核未通过
     */
    private Integer approveStatus;
    /**
     * å®¡æ‰¹æ˜¯å¦åˆ é™¤ï¼š0正常,1删除
     */
    private Integer approveDelete;
    /**
     * ç§Ÿæˆ·id
     */
//    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    /**
     * å®¡æ‰¹ç±»åž‹
     */
    private Integer approveType;
    /**
     * å®¡æ‰¹å¤‡æ³¨
     */
    private String approveRemark;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    private LocalDateTime createTime;
    private static final long serialVersionUID = 1L;
}
src/main/java/com/ruoyi/approve/service/IApproveNodeService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.approve.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.approve.pojo.ApproveNode;
import java.util.List;
public interface IApproveNodeService extends IService<ApproveNode> {
    void initApproveNodes(String approveUserIds,String approveID,Long tenantId);
    /**
     * è¯¦æƒ…
     * @param id
     */
    List<ApproveNode> details(String id);
    void updateApproveNode(ApproveNode approveNode);
    void delApproveNodeByApproveId(Long id);
}
src/main/java/com/ruoyi/approve/service/IApproveProcessService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package com.ruoyi.approve.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.approve.pojo.ApproveNode;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.vo.ApproveGetAndUpdateVo;
import com.ruoyi.approve.vo.ApproveProcessVO;
import com.ruoyi.project.system.domain.SysDept;
import java.text.ParseException;
import java.util.List;
public interface IApproveProcessService extends IService<ApproveProcess> {
    /**
     * æ·»åŠ å®¡æ‰¹æµç¨‹
     * @param approveProcessVO å®¡æ‰¹æµç¨‹VO对象
     */
    void addApprove(ApproveProcessVO approveProcessVO) throws ParseException;
    /**
     * æ ¹æ®éƒ¨é—¨id查询部门信息
     * @param deptIds éƒ¨é—¨ID数组
     */
    List<SysDept> selectDeptListByDeptIds(Long[] deptIds);
    IPage<ApproveProcess> listAll(Page page, ApproveProcess approveProcess);
    void delApprove(Long[] ids);
    void updateByApproveId(ApproveGetAndUpdateVo approveGetAndUpdateVo);
    ApproveProcess getApproveById(String id);
    /**
     * å®¡æ‰¹çŠ¶æ€æ›´æ–°
     * @param approveNode
     */
    void updateApproveProcessStatus(ApproveNode approveNode,Integer status);
}
src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,116 @@
package com.ruoyi.approve.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.approve.mapper.ApproveNodeMapper;
import com.ruoyi.approve.pojo.ApproveNode;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.service.IApproveNodeService;
import com.ruoyi.approve.service.IApproveProcessService;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
@Service
@RequiredArgsConstructor
public class ApproveNodeServiceImpl extends ServiceImpl<ApproveNodeMapper, ApproveNode> implements IApproveNodeService {
    @Autowired
    private  ApproveNodeMapper approveNodeMapper;
    @Autowired
    private  IApproveProcessService approveProcessService;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Override
    public void initApproveNodes(String approveUserIds,String approveID,Long tenantId) {
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        ApproveProcess approve = approveProcessService.getApproveById(approveID);
        String[] names = approveUserIds.split(",");
        String approveId = approve.getApproveId();
        for (int i = 0; i < names.length; i++) {
            SysUser sysUser = sysUserMapper.selectUserById(Long.parseLong(names[i]));
            if (sysUser == null) continue;
            ApproveNode approveNode = new ApproveNode();
            approveNode.setApproveProcessId(approveId);
            approveNode.setApproveNodeOrder(i +1);
            approveNode.setApproveNodeUser(sysUser.getNickName());
            approveNode.setApproveNodeUserId(sysUser.getUserId());
            approveNode.setApproveNodeTime(new Date());
            approveNode.setApproveNodeStatus(0);
            approveNode.setTenantId(tenantId);
            approveNode.setDeleteFlag(0);
            approveNode.setCreateUser(userId);
            approveNode.setUpdateUser(userId);
            approveNode.setCreateTime(LocalDateTime.now());
            approveNode.setUpdateTime(LocalDateTime.now());
            approveNodeMapper.insert(approveNode);
        }
    }
    @Override
    public List<ApproveNode> details(String id) {
        LambdaQueryWrapper<ApproveNode> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApproveNode::getApproveProcessId, id);
        queryWrapper.eq(ApproveNode::getDeleteFlag, 0);
        queryWrapper.eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId());
        List<ApproveNode> list = list(queryWrapper);
        // æŒ‰ç…§ approveNodeOrder å­—段升序排序
        list.sort(Comparator.comparingInt(ApproveNode::getApproveNodeOrder));
        LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>();
        approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveId, id)
                .eq(ApproveProcess::getApproveDelete, 0)
                .eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                .last("limit 1");
        ApproveProcess approveProcess = approveProcessService.getOne(approveProcessLambdaQueryWrapper);
        if(approveProcess != null && approveProcess.getApproveStatus() == 3){
            return list;
        }
        for (ApproveNode approveNode : list) {
            if(approveNode.getApproveNodeStatus() == 1){
                continue;
            }
            approveNode.setIsShen(true);
            break;
        }
        return list;
    }
    @Override
    public void updateApproveNode(ApproveNode approveNode) {
        // å®¡æ‰¹èŠ‚ç‚¹çŠ¶æ€:1同意,2拒绝,0尚未审核
        switch (approveNode.getApproveNodeStatus()){
            case 1:
                approveProcessService.updateApproveProcessStatus(approveNode, Boolean.TRUE.equals(approveNode.getIsLast()) ? 2 : 1);
                break;
            case 2:
                approveProcessService.updateApproveProcessStatus(approveNode, 3);
                break;
            default:
                break;
        }
        approveNode.setApproveNodeTime(new Date());
        approveNodeMapper.updateById(approveNode);
    }
    @Override
    public void delApproveNodeByApproveId(Long id) {
        UpdateWrapper<ApproveNode> queryWrapper = new UpdateWrapper<>();
        queryWrapper.lambda().set(ApproveNode::getDeleteFlag, 1)
                .eq(ApproveNode::getApproveProcessId, id);
        update(queryWrapper);
    }
}
src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,162 @@
package com.ruoyi.approve.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
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.approve.mapper.ApproveProcessMapper;
import com.ruoyi.approve.pojo.ApproveNode;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.service.IApproveNodeService;
import com.ruoyi.approve.service.IApproveProcessService;
import com.ruoyi.approve.utils.DailyRedisCounter;
import com.ruoyi.approve.vo.ApproveGetAndUpdateVo;
import com.ruoyi.approve.vo.ApproveProcessVO;
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.mapper.SysDeptMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@Service
@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;
    @Override
    public void addApprove(ApproveProcessVO approveProcessVO) throws ParseException {
        SysUser sysUser = sysUserMapper.selectUserById(approveProcessVO.getApproveUser());
        SysDept sysDept = sysDeptMapper.selectDeptById(approveProcessVO.getApproveDeptId());
        String[] split = approveProcessVO.getApproveUserIds().split(",");
        List<Long> longList = Arrays.stream(split)
                .map(Long::valueOf)  // å°†æ¯ä¸ª String è½¬æ¢ä¸º Long
                .collect(Collectors.toList());
        List<SysUser> sysUsers = sysUserMapper.selectUserByIds(longList);
        if(CollectionUtils.isEmpty(sysUsers)) throw new RuntimeException("审核用户不存在");
        if(sysDept == null) throw new RuntimeException("部门不存在");
        if(sysUser == null) throw new RuntimeException("申请人不存在");
        String today = LocalDate.now().format(DATE_FORMAT);
        Long approveId = dailyRedisCounter.incrementAndGetByDb();
        String formattedCount = String.format("%03d", approveId);
        //流程 ID
        String approveID = today + formattedCount;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        ApproveProcess approveProcess = new ApproveProcess();
        approveProcess.setApproveId(approveID);
        approveProcess.setApproveUser(approveProcessVO.getApproveUser());
        approveProcess.setApproveUserName(sysUser.getNickName());
        approveProcess.setApproveDeptId(approveProcessVO.getApproveDeptId());
        approveProcess.setApproveDeptName(sysDept.getDeptName());
        approveProcess.setApproveUserNames(sysUsers.stream().map(SysUser::getNickName).collect(Collectors.joining(",")));
        approveProcess.setApproveTime(StringUtils.isEmpty(approveProcessVO.getApproveTime()) ? null : dateFormat.parse(approveProcessVO.getApproveTime()));
        approveProcess.setApproveReason(approveProcessVO.getApproveReason());
        approveProcess.setApproveOverTime(null);
        approveProcess.setApproveStatus(0);
        approveProcess.setApproveDelete(0);
        approveProcess.setCreateTime(LocalDateTime.now());
        approveProcess.setTenantId(approveProcessVO.getApproveDeptId());
        approveProcess.setApproveUserIds(approveProcessVO.getApproveUserIds());
        approveProcess.setApproveUserCurrentId(longList.get(0));
        approveProcess.setApproveUserCurrentName(sysUsers
                .stream()
                .filter(SysUser -> SysUser.getUserId().equals(longList.get(0)))
                .collect(Collectors.toList())
                .get(0)
                .getNickName());
        save(approveProcess);
        //初始化审批节点
        approveNodeService.initApproveNodes(approveProcessVO.getApproveUserIds(),approveID,approveProcessVO.getApproveDeptId());
    }
    @Override
    public List<SysDept> selectDeptListByDeptIds(Long[] deptIds) {
        List<SysDept> sysDeptList =new ArrayList<SysDept>();
        for (Long deptId : deptIds) {
            SysDept sysDept = sysDeptMapper.selectDeptById(deptId);
            sysDeptList.add(sysDept);
        }
        return sysDeptList;
    }
    @Override
    public IPage<ApproveProcess> listAll(Page page,ApproveProcess approveProcess) {
        IPage<ApproveProcess> approveProcessIPage = approveProcessMapper.listPage(page,approveProcess);
        return approveProcessIPage;
    }
    @Override
    public void delApprove(Long[] ids) {
        for (Long id : ids) {
            UpdateWrapper<ApproveProcess> queryWrapper = new UpdateWrapper<>();
            queryWrapper.lambda().set(ApproveProcess::getApproveDelete, 1)
                    .eq(ApproveProcess::getApproveId, id);
            update(queryWrapper);
            // åˆ é™¤å…³è”的审批节点
            approveNodeService.delApproveNodeByApproveId(id);
        }
    }
    @Override
    public ApproveProcess getApproveById(String id) {
        LambdaQueryWrapper<ApproveProcess> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApproveProcess::getApproveId, id);
        queryWrapper.eq(ApproveProcess::getApproveDelete, 0);
        queryWrapper.eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId());
        queryWrapper.last("limit 1");
        ApproveProcess one = getOne(queryWrapper);
        return one;
    }
    @Override
    public void updateApproveProcessStatus(ApproveNode approveNode,Integer status) {
        LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>();
        approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveId, approveNode.getApproveProcessId())
                .eq(ApproveProcess::getApproveDelete, 0)
                .eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                .last("limit 1");
        ApproveProcess approveProcess = approveProcessMapper.selectOne(approveProcessLambdaQueryWrapper);
        if(approveProcess == null) throw new RuntimeException("审批不存在");
        approveProcess.setApproveStatus(status);
        updateById(approveProcess);
    }
    @Override
    public void updateByApproveId(ApproveGetAndUpdateVo approveGetAndUpdateVo) {
        ApproveProcess approve = getApproveById(approveGetAndUpdateVo.getId());
        approve.setApproveReason(approveGetAndUpdateVo.getApproveReason());
        updateById(approve);
    }
}
src/main/java/com/ruoyi/approve/utils/DailyRedisCounter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,129 @@
package com.ruoyi.approve.utils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.approve.mapper.ApproveProcessMapper;
import com.ruoyi.approve.pojo.ApproveProcess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;
//基于redis的一个每日计数器
@Component
public class DailyRedisCounter {
    private static final String KEY_PREFIX = "daily_counter:";
    private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
    private final StringRedisTemplate redisTemplate;
    public DailyRedisCounter(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    /**查缓存
     * èŽ·å–æŒ‡å®šè®¡æ•°å™¨åœ¨ä»Šæ—¥çš„æ•°å€¼ï¼Œå¹¶è‡ªå¢ž1
     * @param counterName è®¡æ•°å™¨åç§°ï¼ˆä¾‹å¦‚:login_count、order_count)
     * @return ä»Šæ—¥è‡ªå¢žåŽçš„计数值
     */
    public long incrementAndGet(String counterName) {
        String key = getKey(counterName);
        long count = redisTemplate.opsForValue().increment(key, 1);
        // ä»…在第一次设置时设置过期时间(避免重复设置)
        if (count == 1) {
            long secondsUntilMidnight = calculateSecondsUntilMidnight();
            redisTemplate.expire(key, secondsUntilMidnight, TimeUnit.SECONDS);
        }
        return count;
    }
    @Autowired
    private ApproveProcessMapper approveProcessMapper;
    /**
     * èŽ·å–å½“å‰æ—¶é—´çš„  å¼€å§‹æ—¥æœŸ  ï¼Œç»“束日期
     * @return
     */
    public static StartAndEndDateDto getDateTime(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE,1);
        String startDateTime = simpleDateFormat.format(date);
        String endDateTime = simpleDateFormat.format(cal.getTime());
        StartAndEndDateDto startAndEndDateDto = new StartAndEndDateDto();
        startAndEndDateDto.setStartDate(startDateTime);
        startAndEndDateDto.setEndDate(endDateTime);
        return startAndEndDateDto;
    }
    /**查数据库
     * èŽ·å–æŒ‡å®šè®¡æ•°å™¨åœ¨ä»Šæ—¥çš„æ•°å€¼ï¼Œå¹¶è‡ªå¢ž1
     * @return ä»Šæ—¥è‡ªå¢žåŽçš„计数值
     */
    public long incrementAndGetByDb() {
        String approveId = redisTemplate.opsForValue().get("approveNum");
        if(approveId == null){
            StartAndEndDateDto dateTime = getDateTime();
            LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>();
            approveProcessLambdaQueryWrapper
                    .eq(ApproveProcess::getApproveDelete,0)
                    .gt(ApproveProcess::getCreateTime,dateTime.getStartDate())
                    .lt(ApproveProcess::getCreateTime,dateTime.getEndDate());
            Long aLong = approveProcessMapper.selectCount(approveProcessLambdaQueryWrapper);
            if(aLong == null){
                redisTemplate.opsForValue().set("approveNum","1",1L, TimeUnit.HOURS);
                return 1;
            }else{
                aLong += 1;
                redisTemplate.opsForValue().set("approveNum",aLong.toString(),1L, TimeUnit.HOURS);
                return aLong;
            }
        }else{
            Long num = Long.parseLong(approveId) + 1;
            redisTemplate.opsForValue().set("approveNum",num.toString(),1L, TimeUnit.HOURS);
            return Long.parseLong(approveId);
        }
    }
    /**
     * èŽ·å–æŒ‡å®šè®¡æ•°å™¨åœ¨ä»Šæ—¥çš„å½“å‰æ•°å€¼
     * @param counterName è®¡æ•°å™¨åç§°
     * @return ä»Šæ—¥å½“前计数值,若不存在则返回0
     */
    public long getCurrentCount(String counterName) {
        String key = getKey(counterName);
        String value = redisTemplate.opsForValue().get(key);
        return value != null ? Long.parseLong(value) : 0;
    }
    /**
     * è®¡ç®—距离次日凌晨的秒数
     */
    private long calculateSecondsUntilMidnight() {
        LocalDate tomorrow = LocalDate.now().plusDays(1);
        LocalDate midnight = tomorrow.atStartOfDay().toLocalDate();
        return java.time.Duration.between(
                LocalDate.now().atTime(23, 59, 59),
                midnight.atTime(0, 0, 0)
        ).getSeconds() + 1;
    }
    /**
     * ç”ŸæˆRedis键
     */
    private String getKey(String counterName) {
        String today = LocalDate.now().format(DATE_FORMAT);
        return KEY_PREFIX + counterName + ":" + today;
    }
}
src/main/java/com/ruoyi/approve/utils/StartAndEndDateDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.ruoyi.approve.utils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author :yys
 * @date : 2023/9/19 10:58
 */
@Data
@ApiModel
public class StartAndEndDateDto {
    @ApiModelProperty("开始时间")
    private String startDate;
    @ApiModelProperty("结束时间")
    private String endDate;
}
src/main/java/com/ruoyi/approve/vo/ApproveGetAndUpdateVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.ruoyi.approve.vo;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class ApproveGetAndUpdateVo {
    //审批id
    @NotBlank(message = "流程编号不能为空")
    private String id;
    //申请事由
    @NotBlank(message = "申请事由不能为空")
    private String approveReason;
}
src/main/java/com/ruoyi/approve/vo/ApproveProcessVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.approve.vo;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class ApproveProcessVO {
    private Long approveDeptId;
    private String approveTime;
    // ç”³è¯·äºº
    private Long approveUser;
    // å®¡æ‰¹äºº
    private String approveUserIds;
    private String approveReason;
}
src/main/java/com/ruoyi/basic/service/impl/SupplierServiceImpl.java
@@ -36,6 +36,11 @@
     */
    @Override
    public void saveSupplier(SupplierManage supplierManage) {
        LambdaQueryWrapper<SupplierManage> supplierManageLambdaQueryWrapper = new LambdaQueryWrapper<>();
        supplierManageLambdaQueryWrapper.eq(SupplierManage::getSupplierName,supplierManage.getSupplierName());
        if (supplierMapper.selectCount(supplierManageLambdaQueryWrapper) > 0) {
            throw new RuntimeException("供应商已存在");
        }
        supplierMapper.insert(supplierManage);
    }
src/main/java/com/ruoyi/framework/security/service/TokenService.java
@@ -1,9 +1,15 @@
package com.ruoyi.framework.security.service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.project.system.domain.SysUserDept;
import com.ruoyi.project.system.mapper.SysUserDeptMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -22,6 +28,7 @@
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.util.CollectionUtils;
/**
 * token验证处理
@@ -140,6 +147,9 @@
        }
    }
    @Autowired
    private SysUserDeptMapper sysUserDeptMapper;
    /**
     * åˆ·æ–°ä»¤ç‰Œæœ‰æ•ˆæœŸ
     * 
@@ -149,6 +159,13 @@
    {
        loginUser.setLoginTime(System.currentTimeMillis());
        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
        LambdaQueryWrapper<SysUserDept> sysUserDeptLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysUserDeptLambdaQueryWrapper.eq(SysUserDept::getUserId, loginUser.getUserId());
        List<SysUserDept> sysUserDept = sysUserDeptMapper.selectList(sysUserDeptLambdaQueryWrapper);
        if(!CollectionUtils.isEmpty(sysUserDept)){
            List<Long> collect = sysUserDept.stream().map(SysUserDept::getDeptId).collect(Collectors.toList());
            loginUser.setDeptId(collect.toArray(new Long[0]));
        }
        // æ ¹æ®uuid将loginUser缓存
        String userKey = getTokenKey(loginUser.getToken());
        redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
src/main/java/com/ruoyi/other/service/impl/TempFileServiceImpl.java
@@ -6,6 +6,7 @@
import com.ruoyi.other.pojo.TempFile;
import com.ruoyi.other.service.TempFileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.util.URLEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
@@ -13,6 +14,7 @@
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -35,7 +37,14 @@
    public TempFile uploadFile(MultipartFile file,Integer type) throws IOException {
        // 1. ç”Ÿæˆä¸´æ—¶æ–‡ä»¶ID和路径
        String tempId = UUID.randomUUID().toString();
        Path tempFilePath = Paths.get(tempDir, tempId + "_" + file.getOriginalFilename());
        String originalFilename = file.getOriginalFilename();
        if(originalFilename == null) throw new IOException("文件名不能为空");
        URLEncoder urlEncoder = new URLEncoder();
        String encodedFilename = urlEncoder.encode(originalFilename, StandardCharsets.UTF_8);
        encodedFilename = encodedFilename.replaceAll("%2E",".");
        Path tempFilePath = Paths.get(tempDir, tempId + "_" + encodedFilename);
//        Path tempFilePath = Paths.get(tempDir, tempId + "_" + file.getOriginalFilename());
        // 2. ç¡®ä¿ç›®å½•存在
        Path parentDir = tempFilePath.getParent();
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
@@ -7,10 +7,7 @@
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.procurementrecord.dto.ProcurementAddDto;
import com.ruoyi.procurementrecord.dto.ProcurementDto;
import com.ruoyi.procurementrecord.dto.ProcurementPageDto;
import com.ruoyi.procurementrecord.dto.ProcurementUpdateDto;
import com.ruoyi.procurementrecord.dto.*;
import com.ruoyi.procurementrecord.service.ProcurementRecordService;
import com.ruoyi.purchase.dto.InvoicePurchaseReportDto;
import com.ruoyi.quality.pojo.QualityInspect;
@@ -56,6 +53,13 @@
        return AjaxResult.success(procurementRecordService.updatePro(procurementDto));
    }
    @PostMapping("/updateManagement")
    @Log(title = "采购入库-库存台账-修改", businessType = BusinessType.UPDATE)
    @Transactional
    public AjaxResult updateManagement(@RequestBody ProcurementManagementUpdateDto procurementDto) {
        return AjaxResult.success(procurementRecordService.updateManagement(procurementDto));
    }
    @PostMapping("/del")
    @Log(title = "采购入库-入库管理-删除入库", businessType = BusinessType.DELETE)
    @Transactional
@@ -70,6 +74,22 @@
        return AjaxResult.success(result);
    }
    @GetMapping("/listPageCopy")
    @Log(title = "采购入库-入库管理-入库查询", businessType = BusinessType.OTHER)
    public AjaxResult listPageCopy(Page page, ProcurementPageDto procurementDto) {
        IPage<ProcurementPageDtoCopy> result =procurementRecordService.listPageCopy(page, procurementDto);
        return AjaxResult.success(result);
    }
    /**
     * å¯¼å‡º
     * @param response
     */
    @PostMapping("/exportCopy")
    public void exportCopy(HttpServletResponse response) {
        procurementRecordService.exportCopy(response);
    }
    /**
     * å¯¼å‡º
     * @param response
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementManagementUpdateDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package com.ruoyi.procurementrecord.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * @author :yys
 * @date : 2025/7/9 9:41
 */
@Data
public class ProcurementManagementUpdateDto {
    private String createBy;
    private Long createUser;
    private String createTime;
    private String entryDate;
    private Integer id;
}
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementPageDto.java
@@ -16,6 +16,8 @@
    private Integer id;
    private Long createUser;
    /**
     * å…¥åº“批次
     */
@@ -38,18 +40,25 @@
    /**
     * å¾…出库数量
     */
    @Excel(name = "待出库数量")
//    @Excel(name = "待出库数量")
    private BigDecimal inboundNum0;
    /**
     * å‡ºå…¥åº“æ—¶é—´
     */
    @Excel(name = "入库时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
//    @Excel(name = "入库时间")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDateTime createTime;
    /**
     * å‡ºå…¥åº“æ—¶é—´
     */
    @Excel(name = "入库时间")
    private String time;
    /**
     * å‡ºå…¥åº“用户
     */
    @Excel(name = "入库人")
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementPageDtoCopy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,128 @@
package com.ruoyi.procurementrecord.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * @author :yys
 * @date : 2025/7/9 10:34
 */
@Data
public class ProcurementPageDtoCopy {
    private Integer id;
    private Long createUser;
    /**
     * å…¥åº“批次
     */
    @Excel(name = "入库批次")
    private String inboundBatches;
    /**
     * åˆåŒå·
     */
    private String purchaseContractNumber;
    private String salesLedgerProductId;
    /**
     * å‡ºå…¥åº“数量
     */
    @Excel(name = "入库数量")
    private BigDecimal inboundNum;
    /**
     * å¾…出库数量
     */
    @Excel(name = "待出库数量")
    private BigDecimal inboundNum0;
    /**
     * å‡ºå…¥åº“æ—¶é—´
     */
//    @Excel(name = "入库时间")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDateTime createTime;
    /**
     * å‡ºå…¥åº“æ—¶é—´
     */
    @Excel(name = "入库时间")
    private String cTime;
    /**
     * å‡ºå…¥åº“æ—¶é—´
     */
//    @Excel(name = "库存时间")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDateTime updateTime;
    /**
     * å‡ºå…¥åº“æ—¶é—´
     */
    @Excel(name = "库存时间")
    private String uTime;
    /**
     * å‡ºå…¥åº“用户
     */
    @Excel(name = "入库人")
    private String createBy;
    /**
     * ä¾›åº”商名称
     */
    @Excel(name = "供应商名称")
    private String supplierName;
    /**
     * äº§å“å¤§ç±»
     */
    @Excel(name = "产品大类")
    private String productCategory;
    /**
     * è§„格型号
     */
    @Excel(name = "规格型号")
    private String specificationModel;
    /**
     * å•位
     */
    @Excel(name = "单位")
    private String unit;
    /**
     * ç¨Žçއ
     */
    @Excel(name = "税率(%)")
    private BigDecimal taxRate;
    /**
     * å«ç¨Žå•ä»·
     */
    @Excel(name = "含税单价")
    private BigDecimal taxInclusiveUnitPrice;
    /**
     * å«ç¨Žæ€»ä»·
     */
    @Excel(name = "含税总价")
    private BigDecimal taxInclusiveTotalPrice;
    /**
     * ä¸å«ç¨Žæ€»ä»·
     */
    @Excel(name = "不含税总价")
    private BigDecimal taxExclusiveTotalPrice;
}
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementRecordOutPageDto.java
@@ -25,10 +25,13 @@
    /**
     * å‡ºå…¥åº“æ—¶é—´
     */
    @Excel(name = "出库时间")
//    @Excel(name = "出库时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime createTime;
    @Excel(name = "出库时间")
    private String time;
    /**
     * å‡ºå…¥åº“用户
     */
src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordMapper.java
@@ -5,6 +5,7 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.procurementrecord.dto.ProcurementDto;
import com.ruoyi.procurementrecord.dto.ProcurementPageDto;
import com.ruoyi.procurementrecord.dto.ProcurementPageDtoCopy;
import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
import org.apache.ibatis.annotations.Param;
@@ -25,5 +26,9 @@
    IPage<ProcurementPageDto> listPage(Page page,@Param("req")  ProcurementPageDto procurementDto);
    IPage<ProcurementPageDtoCopy> listPageCopy(Page page, @Param("req")  ProcurementPageDto procurementDto);
    List<ProcurementPageDtoCopy> listCopy();
    List<ProcurementPageDto> list();
}
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordOut.java
@@ -1,8 +1,6 @@
package com.ruoyi.procurementrecord.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Builder;
import lombok.Data;
@@ -70,6 +68,7 @@
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java
@@ -1,8 +1,6 @@
package com.ruoyi.procurementrecord.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Builder;
import lombok.Data;
@@ -66,5 +64,6 @@
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java
@@ -3,10 +3,7 @@
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.procurementrecord.dto.ProcurementAddDto;
import com.ruoyi.procurementrecord.dto.ProcurementDto;
import com.ruoyi.procurementrecord.dto.ProcurementPageDto;
import com.ruoyi.procurementrecord.dto.ProcurementUpdateDto;
import com.ruoyi.procurementrecord.dto.*;
import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
import javax.servlet.http.HttpServletResponse;
@@ -23,9 +20,15 @@
    IPage<ProcurementPageDto> listPage(Page page, ProcurementPageDto procurementDto);
    IPage<ProcurementPageDtoCopy> listPageCopy(Page page, ProcurementPageDto procurementDto);
    int updatePro(ProcurementUpdateDto procurementDto);
    int deletePro(ProcurementUpdateDto procurementDto);
    void export(HttpServletResponse response);
    int updateManagement(ProcurementManagementUpdateDto procurementDto);
    void exportCopy(HttpServletResponse response);
}
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordOutServiceImpl.java
@@ -56,8 +56,7 @@
                .createUser(Long.valueOf(procurementRecordOutAdd.getUserId()))
                .createBy(sysUser.getNickName())
                .updateUser(Long.valueOf(procurementRecordOutAdd.getUserId()))
                .updateTime(LocalDateTime.now())
                .tenantId(sysUser.getTenantId());
                .updateTime(LocalDateTime.now());
        this.save(procurementRecordOut.build());
        return 0;
    }
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
@@ -4,6 +4,7 @@
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.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.security.LoginUser;
@@ -13,7 +14,10 @@
import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut;
import com.ruoyi.procurementrecord.service.ProcurementRecordService;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -22,6 +26,7 @@
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
@@ -120,8 +125,109 @@
    @Override
    public void export(HttpServletResponse response) {
        List<ProcurementPageDto> list =procurementRecordMapper.list();
        // è®¡ç®—待入库数量
        // æŸ¥è¯¢é‡‡è´­è®°å½•已入库数量
        List<Integer> collect = list.stream().map(ProcurementPageDto::getId).collect(Collectors.toList());
        if(CollectionUtils.isEmpty( collect)){
        ExcelUtil<ProcurementPageDto> util = new ExcelUtil<ProcurementPageDto>(ProcurementPageDto.class);
        util.exportExcel(response, list, "入库台账");
            return;
        }
        LambdaQueryWrapper<ProcurementRecordOut> procurementRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        procurementRecordLambdaQueryWrapper.in(ProcurementRecordOut::getProcurementRecordStorageId, collect);
        List<ProcurementRecordOut> procurementRecords = procurementRecordOutMapper.selectList(procurementRecordLambdaQueryWrapper);
        if(CollectionUtils.isEmpty( procurementRecords)){
            ExcelUtil<ProcurementPageDto> util = new ExcelUtil<ProcurementPageDto>(ProcurementPageDto.class);
            util.exportExcel(response, list, "入库台账");
            return;
        }
        for (ProcurementPageDto dto : list) {
            // æ ¹æ®é‡‡è´­å°è´¦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));
        }
        ExcelUtil<ProcurementPageDto> util = new ExcelUtil<ProcurementPageDto>(ProcurementPageDto.class);
        util.exportExcel(response, list, "入库台账");
    }
    private final SysUserMapper sysUserMapper;
    @Override
    public int updateManagement(ProcurementManagementUpdateDto procurementDto) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = sysUserMapper.selectUserById(procurementDto.getCreateUser());
        if(sysUser == null){
            throw new RuntimeException("入库人不存在");
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String entryDateStr = procurementDto.getEntryDate() + " 00:00:00";
        String createTimeStr = procurementDto.getCreateTime() + " 00:00:00";
        ProcurementRecordStorage procurementRecordStorageById = getProcurementRecordById(procurementDto.getId());
        procurementRecordStorageById.setCreateBy(sysUser.getNickName());
        procurementRecordStorageById.setCreateUser(sysUser.getUserId());
        procurementRecordStorageById.setUpdateTime(LocalDateTime.parse(entryDateStr,df));
        procurementRecordStorageById.setUpdateUser(loginUser.getUserId());
        procurementRecordStorageById.setCreateTime(LocalDateTime.parse(createTimeStr,df));
        procurementRecordMapper.updateById(procurementRecordStorageById);
        return 0;
    }
    @Override
    public void exportCopy(HttpServletResponse response) {
        List<ProcurementPageDtoCopy> list =procurementRecordMapper.listCopy();
        // è®¡ç®—待入库数量
        // æŸ¥è¯¢é‡‡è´­è®°å½•已入库数量
        List<Integer> collect = list.stream().map(ProcurementPageDtoCopy::getId).collect(Collectors.toList());
        if(CollectionUtils.isEmpty( collect)){
            ExcelUtil<ProcurementPageDtoCopy> util = new ExcelUtil<ProcurementPageDtoCopy>(ProcurementPageDtoCopy.class);
            util.exportExcel(response, list, "库存管理");
            return;
        }
        LambdaQueryWrapper<ProcurementRecordOut> procurementRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        procurementRecordLambdaQueryWrapper.in(ProcurementRecordOut::getProcurementRecordStorageId, collect);
        List<ProcurementRecordOut> procurementRecords = procurementRecordOutMapper.selectList(procurementRecordLambdaQueryWrapper);
        if(CollectionUtils.isEmpty( procurementRecords)){
            ExcelUtil<ProcurementPageDtoCopy> util = new ExcelUtil<ProcurementPageDtoCopy>(ProcurementPageDtoCopy.class);
            util.exportExcel(response, list, "库存管理");
            return;
        }
        for (ProcurementPageDtoCopy dto : list) {
            // æ ¹æ®é‡‡è´­å°è´¦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));
        }
        ExcelUtil<ProcurementPageDtoCopy> util = new ExcelUtil<ProcurementPageDtoCopy>(ProcurementPageDtoCopy.class);
        util.exportExcel(response, list, "库存管理");
    }
    @Override
@@ -142,7 +248,6 @@
                    .createUser(loginUser.getUserId())
                    .updateTime(LocalDateTime.now())
                    .updateUser(loginUser.getUserId())
                    .tenantId(loginUser.getTenantId())
                    .createBy(procurementDto.getNickName());
            this.save(procurementRecordBuilder.build());
            // å…¥åº“成功减掉采购数量
@@ -197,4 +302,43 @@
        return procurementPageDtoIPage;
    }
    @Override
    public IPage<ProcurementPageDtoCopy> listPageCopy(Page page, ProcurementPageDto procurementDto) {
        IPage<ProcurementPageDtoCopy> procurementPageDtoCopyIPage = procurementRecordMapper.listPageCopy(page, procurementDto);
        List<ProcurementPageDtoCopy> procurementPageDtoCopyList = procurementPageDtoCopyIPage.getRecords();
        // è®¡ç®—待入库数量
        // æŸ¥è¯¢é‡‡è´­è®°å½•已入库数量
        List<Integer> collect = procurementPageDtoCopyList.stream().map(ProcurementPageDtoCopy::getId).collect(Collectors.toList());
        if(CollectionUtils.isEmpty( collect)){
            return procurementPageDtoCopyIPage;
        }
        LambdaQueryWrapper<ProcurementRecordOut> procurementRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        procurementRecordLambdaQueryWrapper.in(ProcurementRecordOut::getProcurementRecordStorageId, collect);
        List<ProcurementRecordOut> procurementRecords = procurementRecordOutMapper.selectList(procurementRecordLambdaQueryWrapper);
        if(CollectionUtils.isEmpty( procurementRecords)){
            return procurementPageDtoCopyIPage;
        }
        for (ProcurementPageDtoCopy dto : procurementPageDtoCopyList) {
            // æ ¹æ®é‡‡è´­å°è´¦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 procurementPageDtoCopyIPage;
    }
}
src/main/java/com/ruoyi/project/system/controller/SysUserController.java
@@ -269,4 +269,18 @@
        List<SysUser> sysUserList = userService.userListNoPage(user);
        return AjaxResult.success(sysUserList);
    }
    /**
     * æŸ¥è¯¢å½“前用户公司下所有用户
     * @param user
     * @return
     */
    @GetMapping("/userListNoPageByTenantId")
    public AjaxResult userListNoPageByTenantId(SysUser user){
        //获取登录用户信息
        SysUser loginUser = SecurityUtils.getLoginUser().getUser();
        user.setTenantId(loginUser.getTenantId());
        List<SysUser> sysUserList = userService.userListNoPage(user);
        return AjaxResult.success(sysUserList);
    }
}
src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java
@@ -54,6 +54,14 @@
    public SysUser selectUserById(Long userId);
    /**
     * é€šè¿‡ç”¨æˆ·ID查询用户
     *
     * @param userId ç”¨æˆ·ID
     * @return ç”¨æˆ·å¯¹è±¡ä¿¡æ¯
     */
    public List<SysUser> selectUserByIds(@Param("userIds") List<Long> userId);
    /**
     * æ–°å¢žç”¨æˆ·ä¿¡æ¯
     * 
     * @param user ç”¨æˆ·ä¿¡æ¯
src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java
@@ -12,6 +12,7 @@
import com.ruoyi.project.system.mapper.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
@@ -178,6 +178,7 @@
        List<Long> salesLedgerIds = iPage.getRecords().stream().map(SalesLedger::getId).collect(Collectors.toList());
        List<InvoiceLedgerDto> invoiceLedgerDtoList = invoiceLedgerMapper.invoicedTotal(salesLedgerIds);
        if(CollectionUtils.isEmpty(invoiceLedgerDtoList)){
            iPage.setTotal(iPage.getRecords().size());
            return iPage;
        }
        for (SalesLedger salesLedger : iPage.getRecords()) {
@@ -204,6 +205,7 @@
                iPage.getRecords().removeIf(salesLedger -> Objects.equals(salesLedger.getNoInvoiceAmountTotal(), new BigDecimal("0.00")));
            }
        }
        iPage.setTotal(iPage.getRecords().size());
        return iPage;
    }
}
src/main/java/com/ruoyi/staff/controller/StaffOnJobController.java
@@ -36,6 +36,15 @@
    }
    /**
     * åœ¨èŒå‘˜å·¥ä¸‹æ‹‰(新增离职用)
     * @return
     */
    @GetMapping("/list")
    public AjaxResult staffOnJobList() {
        return AjaxResult.success(staffOnJobService.staffOnJobList());
    }
    /**
     * åœ¨èŒå‘˜å·¥è¯¦æƒ…
     * @param staffNo
     * @return
src/main/java/com/ruoyi/staff/service/IStaffOnJobService.java
@@ -17,4 +17,6 @@
    List<StaffJoinLeaveRecord> staffOnJobDetail(String staffNo);
    void staffOnJobExport(HttpServletResponse response, StaffOnJob staffOnJob);
    List<StaffOnJob> staffOnJobList();
}
src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
@@ -50,6 +50,10 @@
        util.exportExcel(response, staffOnJobs, "在职员工台账导出");
    }
    @Override
    public List<StaffOnJob> staffOnJobList() {
        return staffOnJobMapper.selectList(Wrappers.<StaffOnJob>lambdaQuery().eq(StaffOnJob::getStaffState,1));
    }
}
src/main/resources/application.yml
@@ -83,7 +83,7 @@
    # æ•°æ®åº“索引
    database: 0
    # å¯†ç 
    password:
    password: root2022!
#    password: 123456
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
src/main/resources/mapper/approve/ApproveLogMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
<?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.approve.mapper.ApproveLogMapper">
    <resultMap id="BaseResultMap" type="com.ruoyi.approve.pojo.ApproveLog">
            <id property="id" column="id" />
            <result property="approveId" column="approve_id" />
            <result property="approveNodeOrder" column="approve_node_order" />
            <result property="approveUser" column="approve_user" />
            <result property="approveTime" column="approve_time" />
            <result property="approveStatus" column="approve_status" />
            <result property="approveRemark" column="approve_remark" />
    </resultMap>
    <sql id="Base_Column_List">
        id,approve_id,approve_node_order,approve_user,approve_time,approve_status,
        approve_remark
    </sql>
</mapper>
src/main/resources/mapper/approve/ApproveNodeMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
<?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.approve.mapper.ApproveNodeMapper">
    <resultMap id="BaseResultMap" type="com.ruoyi.approve.pojo.ApproveNode">
            <id property="id" column="id" />
            <result property="approveProcessId" column="approve_process_id" />
            <result property="approveNodeOrder" column="approve_node_order" />
            <result property="approveNodeUser" column="approve_node_user" />
            <result property="approveNodeTime" column="approve_node_time" />
            <result property="approveNodeStatus" column="approve_node_status" />
            <result property="tenantId" column="tenant_id" />
            <result property="deleteFlag" column="delete_flag" />
            <result property="approveNodeReason" column="approve_node_reason" />
            <result property="approveNodeRemark" column="approve_node_remark" />
    </resultMap>
    <sql id="Base_Column_List">
        id,approve_process_id,approve_node_order,approve_node_user,approve_node_time,approve_node_status,
        tenant_id,delete_flag,approve_node_reason,approve_node_remark
    </sql>
</mapper>
src/main/resources/mapper/approve/ApproveProcessMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
<?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.approve.mapper.ApproveProcessMapper">
    <resultMap id="BaseResultMap" type="com.ruoyi.approve.pojo.ApproveProcess">
            <id property="id" column="id" />
            <result property="approveId" column="approve_id" />
            <result property="approveUser" column="approve_user" />
            <result property="approveDeptId" column="approve_dept_id" />
            <result property="approveDeptName" column="approve_dept_name" />
            <result property="approveUserIds" column="approve_user_ids" />
            <result property="approveUserNames" column="approve_user_names" />
            <result property="approveReason" column="approve_reason" />
            <result property="approveTime" column="approve_time" />
            <result property="approveOverTime" column="approve_over_time" />
            <result property="approveStatus" column="approve_status" />
            <result property="approveDelete" column="approve_delete" />
            <result property="tenantId" column="tenant_id" />
            <result property="approveType" column="approve_type" />
            <result property="approveRemark" column="approve_remark" />
    </resultMap>
    <sql id="Base_Column_List">
        id,approve_id,approve_user,approve_dept_id,approve_dept_name,approve_user_ids,
        approve_user_names,approve_reason,approve_time,approve_over_time,approve_status,
        approve_delete,tenant_id,approve_type,approve_remark
    </sql>
    <select id="listPage" resultType="com.ruoyi.approve.pojo.ApproveProcess">
        select * from approve_process where approve_delete = 0
        <if test="req.approveId != null and req.approveId != ''">
            and approve_id like concat('%',#{req.approveId},'%')
        </if>
    </select>
</mapper>
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
@@ -33,6 +33,7 @@
        t2.product_category,
        t1.id,
        t1.sales_ledger_product_id,
        t1.create_user,
        t2.specification_model,
        t2.unit,
        t2.tax_rate,
@@ -43,6 +44,7 @@
        t1.inbound_num,
        t1.inbound_num as inboundNum0,
        t1.create_time,
        t1.update_time,
        t1.create_by
        from  procurement_record_storage t1
                  left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
@@ -71,6 +73,63 @@
            t1.inbound_batches,
            t1.inbound_num,
            t1.create_time,
            t1.create_time as time,
            t1.create_by
        from  procurement_record_storage t1
                  left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
                  left join purchase_ledger t3 on t3.id = t2.sales_ledger_id
    </select>
    <select id="listPageCopy" resultType="com.ruoyi.procurementrecord.dto.ProcurementPageDtoCopy">
        select
        t3.supplier_name,
        t3.purchase_contract_number,
        t2.product_category,
        t1.id,
        t1.sales_ledger_product_id,
        t1.create_user,
        t2.specification_model,
        t2.unit,
        t2.tax_rate,
        t2.tax_inclusive_unit_price,
        t2.tax_inclusive_total_price,
        t2.tax_exclusive_total_price,
        t1.inbound_batches,
        t1.inbound_num,
        t1.inbound_num as inboundNum0,
        t1.create_time,
        t1.update_time,
        t1.create_by
        from  procurement_record_storage t1
        left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
        left join purchase_ledger t3 on t3.id = t2.sales_ledger_id
        <where>
            1 = 1
            <if test="req.supplierName != null and req.supplierName != ''">
                and t3.supplier_name like  concat('%',#{req.supplierName},'%')
            </if>
        </where>
    </select>
    <select id="listCopy" resultType="com.ruoyi.procurementrecord.dto.ProcurementPageDtoCopy">
        select
            t3.supplier_name,
            t3.purchase_contract_number,
            t2.product_category,
            t1.id,
            t1.sales_ledger_product_id,
            t1.create_user,
            t2.specification_model,
            t2.unit,
            t2.tax_rate,
            t2.tax_inclusive_unit_price,
            t2.tax_inclusive_total_price,
            t2.tax_exclusive_total_price,
            t1.inbound_batches,
            t1.inbound_num,
            t1.inbound_num as inboundNum0,
            t1.create_time,
            t1.update_time,
            t1.create_time as cTime,
            t1.update_time as uTime,
            t1.create_by
        from  procurement_record_storage t1
                  left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml
@@ -39,6 +39,7 @@
            t2.tax_exclusive_total_price,
            t1.inbound_num,
            t1.create_time,
            t1.create_time as time,
            t1.create_by
        from  procurement_record_out t1
                  left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
src/main/resources/mapper/purchase/ProductRecordMapper.xml
@@ -27,7 +27,7 @@
            and sl.sales_contract_no = #{c.salesContractNo}
        </if>
        <if test="c.supplierName != null and c.supplierName != ''">
            and sl.supplier_name = #{c.supplierName}
            and pl.supplier_name = #{c.supplierName}
        </if>
        <if test="c.createdAtStart != null and c.createdAtStart != ''">
            and pr.created_at &gt;= date_format(#{c.createdAtStart},'%Y-%m-%d hh:mm:ss')
src/main/resources/mapper/quality/QualityUnqualifiedMapper.xml
@@ -7,10 +7,10 @@
        FROM quality_unqualified
        where
        1=1
        <if test="qualityUnqualified.inspectType != null and qualityUnqualified.inspectType != '' ">
        <if test="qualityUnqualified.inspectType != null ">
            AND inspect_type = #{qualityUnqualified.inspectType}
        </if>
        <if test="qualityUnqualified.inspectState != null and qualityUnqualified.inspectState != '' ">
        <if test="qualityUnqualified.inspectState != null ">
            AND inspect_state = #{qualityUnqualified.inspectState}
        </if>
        <if test="qualityUnqualified.productName != null and qualityUnqualified.productName != '' ">
@@ -23,10 +23,10 @@
        FROM quality_unqualified
        where
        1=1
        <if test="qualityUnqualified.inspectType != null and qualityUnqualified.inspectType != '' ">
        <if test="qualityUnqualified.inspectType != null">
            AND inspect_type = #{qualityUnqualified.inspectType}
        </if>
        <if test="qualityUnqualified.inspectState != null and qualityUnqualified.inspectState != '' ">
        <if test="qualityUnqualified.inspectState != null">
            AND inspect_state = #{qualityUnqualified.inspectState}
        </if>
        <if test="qualityUnqualified.productName != null and qualityUnqualified.productName != '' ">
src/main/resources/mapper/system/SysDeptMapper.xml
@@ -67,7 +67,7 @@
    </select>
    
    <select id="checkDeptExistUser" parameterType="Long" resultType="int">
        select count(1) from sys_user where dept_id = #{deptId} and del_flag = '0'
        select count(1) from sys_user_dept where dept_id = #{deptId}
    </select>
    
    <select id="hasChildByDeptId" parameterType="Long" resultType="int">
src/main/resources/mapper/system/SysUserMapper.xml
@@ -62,6 +62,11 @@
            FROM
                sys_user_dept T1
            LEFT JOIN sys_dept T2 ON T1.dept_id = T2.dept_id
        <where>
            <if test="tenantId != null and tenantId != 0">
                T1.dept_id = #{tenantId}
            </if>
        </where>
            GROUP BY T1.user_id
        ) T2 on T2.user_id = u.user_id
        where u.del_flag = '0'
@@ -147,6 +152,12 @@
    <select id="checkEmailUnique" parameterType="String" resultMap="SysUserResult">
        select user_id, email from sys_user where email = #{email} and del_flag = '0' limit 1
    </select>
    <select id="selectUserByIds" resultType="com.ruoyi.project.system.domain.SysUser">
        <include refid="selectUserVo"/>
        where u.user_id in <foreach collection="userIds" item="item" open="(" separator="," close=")">
             #{item}
        </foreach>
    </select>
    
    <insert id="insertUser" parameterType="com.ruoyi.project.system.domain.SysUser" useGeneratedKeys="true" keyProperty="userId">
         insert into sys_user(