已添加12个文件
已修改3个文件
726 ■■■■■ 文件已修改
src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesNearExpiryController.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesServiceFileController.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/mapper/AfterSalesNearExpiryMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/mapper/AfterSalesServiceFileMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/pojo/AfterSalesNearExpiry.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/pojo/AfterSalesServiceFile.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/service/AfterSalesNearExpiryService.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/service/AfterSalesServiceFileService.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesNearExpiryServiceImpl.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceFileServiceImpl.java 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/controller/ApproveProcessController.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/utils/DailyRedisCounter.java 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/vo/ApproveProcessVO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/aftersalesservice/AfterSalesNearExpiryMapper.xml 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/aftersalesservice/AfterSalesServiceFileMapper.xml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesNearExpiryController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
package com.ruoyi.aftersalesservice.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.aftersalesservice.pojo.AfterSalesNearExpiry;
import com.ruoyi.aftersalesservice.service.AfterSalesNearExpiryService;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
 * <br>
 * ä¸´æœŸå”®åŽç®¡ç†æŽ§åˆ¶å±‚
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/02 14:40
 */
@RestController
@Api(tags = "临期售后管理")
@RequestMapping("/afterSalesNearExpiryService")
public class AfterSalesNearExpiryController extends BaseController {
    @Autowired
    private AfterSalesNearExpiryService afterSalesNearExpiryService;
    /**
     * æ–°å¢žä¸´æœŸå”®åŽ
     */
    @PostMapping("/add")
    @ApiOperation("新增临期售后")
    @Log(title = "新增临期售后", businessType = BusinessType.INSERT)
    public AjaxResult add(@RequestBody AfterSalesNearExpiry entity) {
        afterSalesNearExpiryService.add(entity);
        return AjaxResult.success("添加成功");
    }
    /**
     * æ›´æ–°ä¸´æœŸå”®åŽ
     */
    @PostMapping("/update")
    @ApiOperation("更新临期售后")
    @Log(title = "更新临期售后", businessType = BusinessType.UPDATE)
    public AjaxResult update(@RequestBody AfterSalesNearExpiry entity) {
        afterSalesNearExpiryService.update(entity);
        return AjaxResult.success("更新成功");
    }
    /**
     * åˆ é™¤ä¸´æœŸå”®åŽ
     */
    @DeleteMapping("/delete")
    @ApiOperation("删除临期售后")
    @Log(title = "删除临期售后", businessType = BusinessType.DELETE)
    public AjaxResult delete(Long[] ids) {
        afterSalesNearExpiryService.delete(ids);
        return AjaxResult.success("删除成功");
    }
    /**
     * åˆ†é¡µæŸ¥è¯¢ä¸´æœŸå”®åŽ
     */
    @GetMapping("/listPage")
    @ApiOperation("分页查询临期售后")
    @Log(title = "分页查询临期售后", businessType = BusinessType.OTHER)
    public AjaxResult listPage(Page<AfterSalesNearExpiry> page, AfterSalesNearExpiry entity) {
        IPage<AfterSalesNearExpiry> listPage = afterSalesNearExpiryService.listPage(page, entity);
        return AjaxResult.success(listPage);
    }
}
src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesServiceFileController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
package com.ruoyi.aftersalesservice.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.aftersalesservice.pojo.AfterSalesServiceFile;
import com.ruoyi.aftersalesservice.service.AfterSalesServiceFileService;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
 * <br>
 * å”®åŽæœåŠ¡é™„ä»¶è¡¨æŽ§åˆ¶å±‚
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/02 11:20
 */
@RestController
@Api(tags = "售后服务附件表")
@RequestMapping("/afterSalesService/file")
public class AfterSalesServiceFileController extends BaseController {
    @Autowired
    private AfterSalesServiceFileService afterSalesServiceFileService;
    @PostMapping("/upload")
    @ApiOperation("售后服务-文件上传")
    @Log(title = "售后服务-文件上传", businessType = BusinessType.INSERT)
    public AjaxResult fileUpload(@RequestParam("file") MultipartFile file,
                                 @RequestParam("id") Long afterSalesServiceId) {
        afterSalesServiceFileService.fileUpload(file, afterSalesServiceId);
        return AjaxResult.success("上传成功");
    }
    @GetMapping("/listPage")
    @ApiOperation("售后处理-售后附件列表")
    @Log(title = "售后处理-售后附件列表", businessType = BusinessType.OTHER)
    public AjaxResult fileList(Page<AfterSalesServiceFile> page, Long afterSalesServiceId) {
        return AjaxResult.success(afterSalesServiceFileService.fileList(page, afterSalesServiceId));
    }
    @DeleteMapping("/del/{fileId}")
    @ApiOperation("售后处理-删除附件")
    @Log(title = "售后处理-删除附件", businessType = BusinessType.DELETE)
    public AjaxResult delFile(@PathVariable Long fileId) {
        afterSalesServiceFileService.delFile(fileId);
        return AjaxResult.success("删除成功!");
    }
}
src/main/java/com/ruoyi/aftersalesservice/mapper/AfterSalesNearExpiryMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.aftersalesservice.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.aftersalesservice.pojo.AfterSalesNearExpiry;
import org.apache.ibatis.annotations.Param;
/**
 * <br>
 * ä¸´æœŸå”®åŽç®¡ç†Mapper
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/02 14:44
 */
public interface AfterSalesNearExpiryMapper extends BaseMapper<AfterSalesNearExpiry> {
    IPage<AfterSalesNearExpiry> listPage(Page<AfterSalesNearExpiry> page, @Param("req") AfterSalesNearExpiry entity);
}
src/main/java/com/ruoyi/aftersalesservice/mapper/AfterSalesServiceFileMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.aftersalesservice.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.aftersalesservice.pojo.AfterSalesServiceFile;
/**
 * <br>
 *
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/02 11:15
 */
public interface AfterSalesServiceFileMapper extends BaseMapper<AfterSalesServiceFile> {
}
src/main/java/com/ruoyi/aftersalesservice/pojo/AfterSalesNearExpiry.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,91 @@
package com.ruoyi.aftersalesservice.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 io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
 * <br>
 * ä¸´æœŸå”®åŽç®¡ç†å®žä½“ç±»
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/02 14:41
 */
@Data
@TableName("after_sales_near_expiry")
@ApiModel("临期售后管理表")
public class AfterSalesNearExpiry {
    @TableId(type = IdType.AUTO)
    @ApiModelProperty("主键")
    private Long id;
    @ApiModelProperty("临期产品名称")
    private String productName;
    @ApiModelProperty("产品批号")
    private String batchNumber;
    @ApiModelProperty("临期日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate expireDate;
    @ApiModelProperty("库存数量")
    private Integer stockQuantity;
    @ApiModelProperty("客户名称")
    private String customerName;
    @ApiModelProperty("联系电话")
    private String contactPhone;
    @ApiModelProperty("问题描述")
    private String disRes;
    @ApiModelProperty("处理结果")
    private String disposeResult;
    @ApiModelProperty("处理状态 (1-待处理 2-已处理)")
    private Integer status;
    @ApiModelProperty("处理人ID")
    private Long disposeUserId;
    @ApiModelProperty("处理人名称")
    private String disposeNickName;
    @ApiModelProperty("处理日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate disDate;
    @ApiModelProperty("创建者")
    private Long createUser;
    @ApiModelProperty("创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty("修改者")
    private Long updateUser;
    @ApiModelProperty("修改时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @ApiModelProperty("租户id")
    private Long tenantId;
}
src/main/java/com/ruoyi/aftersalesservice/pojo/AfterSalesServiceFile.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
package com.ruoyi.aftersalesservice.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
 * <br>
 * å”®åŽæœåŠ¡é™„ä»¶å®žä½“ç±»
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/02 11:13
 */
@Data
@TableName("after_sales_service_file")
@ApiModel("售后服务附件表")
public class AfterSalesServiceFile {
    @TableId(type = IdType.AUTO)
    @ApiModelProperty("主键")
    private Long id;
    @ApiModelProperty("售后服务记录ID")
    private Long serviceId;
    @ApiModelProperty("文件名称")
    private String fileName;
    @ApiModelProperty("文件访问地址")
    private String fileUrl;
    @ApiModelProperty("文件大小")
    private Long fileSize;
    @ApiModelProperty("文件后缀")
    private String fileSuffix;
    @ApiModelProperty("删除标志(0代表存在 1代表删除)")
    private String delFlag;
    @ApiModelProperty("上传者")
    private Long createUser;
    @ApiModelProperty("创建时间")
    private LocalDateTime createTime;
    @ApiModelProperty("修改者")
    private Long updateUser;
    @ApiModelProperty("修改时间")
    private LocalDateTime updateTime;
    @ApiModelProperty("租户id")
    private Long tenantId;
}
src/main/java/com/ruoyi/aftersalesservice/service/AfterSalesNearExpiryService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.ruoyi.aftersalesservice.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.aftersalesservice.pojo.AfterSalesNearExpiry;
/**
 * <br>
 * ä¸´æœŸå”®åŽç®¡ç†æŽ¥å£
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/02 14:45
 */
public interface AfterSalesNearExpiryService extends IService<AfterSalesNearExpiry> {
    void add(AfterSalesNearExpiry entity);
    void update(AfterSalesNearExpiry entity);
    void delete(Long[] ids);
    IPage<AfterSalesNearExpiry> listPage(Page<AfterSalesNearExpiry> page, AfterSalesNearExpiry entity);
}
src/main/java/com/ruoyi/aftersalesservice/service/AfterSalesServiceFileService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.ruoyi.aftersalesservice.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.aftersalesservice.pojo.AfterSalesServiceFile;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
 * <br>
 * å”®åŽæœåŠ¡é™„ä»¶è¡¨æŽ¥å£
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/02 11:18
 */
public interface AfterSalesServiceFileService extends IService<AfterSalesServiceFile> {
    void fileUpload(MultipartFile file, Long afterSalesServiceId);
    IPage<AfterSalesServiceFile> fileList(Page<AfterSalesServiceFile> page, Long afterSalesServiceId);
    void delFile(Long fileId);
}
src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesNearExpiryServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,89 @@
package com.ruoyi.aftersalesservice.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.aftersalesservice.mapper.AfterSalesNearExpiryMapper;
import com.ruoyi.aftersalesservice.pojo.AfterSalesNearExpiry;
import com.ruoyi.aftersalesservice.service.AfterSalesNearExpiryService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Arrays;
/**
 * <br>
 * ä¸´æœŸå”®åŽç®¡ç†æŽ¥å£å®žçŽ°ç±»
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/02 14:46
 */
@Service
public class AfterSalesNearExpiryServiceImpl extends ServiceImpl<AfterSalesNearExpiryMapper, AfterSalesNearExpiry> implements AfterSalesNearExpiryService {
    @Override
    public void add(AfterSalesNearExpiry entity) {
        if (entity == null) {
            throw new ServiceException("添加失败,数据不能为空");
        }
        if (entity.getProductName() == null || entity.getProductName().trim().isEmpty()) {
            throw new ServiceException("产品名称不能为空");
        }
        if (entity.getBatchNumber() == null || entity.getBatchNumber().trim().isEmpty()) {
            throw new ServiceException("产品批号不能为空");
        }
        if (entity.getExpireDate() == null) {
            throw new ServiceException("临期日期不能为空");
        }
        entity.setId(null);
        entity.setStatus(1);
        entity.setDisposeUserId(null);
        entity.setDisposeNickName(null);
        entity.setDisDate(null);
        entity.setCreateTime(LocalDateTime.now());
        entity.setCreateUser(SecurityUtils.getLoginUser().getUserId());
        entity.setUpdateUser(null);
        entity.setUpdateTime(null);
        entity.setTenantId(SecurityUtils.getLoginUser().getTenantId());
        int result = baseMapper.insert(entity);
        if (result <= 0) {
            throw new ServiceException("新增失败");
        }
    }
    @Override
    public void update(AfterSalesNearExpiry entity) {
        if (entity == null || entity.getId() == null) {
            throw new ServiceException("更新失败,数据不完整");
        }
        entity.setStatus(2);
        entity.setUpdateUser(SecurityUtils.getLoginUser().getUserId());
        entity.setUpdateTime(LocalDateTime.now());
        int result = baseMapper.updateById(entity);
        if (result <= 0) {
            throw new ServiceException("更新失败");
        }
    }
    @Override
    public void delete(Long[] ids) {
        if (ids == null || ids.length == 0) {
            throw new ServiceException("请选择要删除的数据");
        }
        int result = baseMapper.deleteBatchIds(Arrays.asList(ids));
        if (result <= 0) {
            throw new ServiceException("删除失败");
        }
    }
    @Override
    public IPage<AfterSalesNearExpiry> listPage(Page<AfterSalesNearExpiry> page, AfterSalesNearExpiry entity) {
        return baseMapper.listPage(page, entity);
    }
}
src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceFileServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,137 @@
package com.ruoyi.aftersalesservice.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.aftersalesservice.mapper.AfterSalesServiceFileMapper;
import com.ruoyi.aftersalesservice.pojo.AfterSalesService;
import com.ruoyi.aftersalesservice.pojo.AfterSalesServiceFile;
import com.ruoyi.aftersalesservice.service.AfterSalesServiceFileService;
import com.ruoyi.aftersalesservice.service.AfterSalesServiceService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
/**
 * <br>
 * å”®åŽæœåŠ¡é™„ä»¶è¡¨æŽ¥å£å®žçŽ°ç±»
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/02 11:19
 */
@Service
public class AfterSalesServiceFileServiceImpl extends ServiceImpl<AfterSalesServiceFileMapper, AfterSalesServiceFile> implements AfterSalesServiceFileService {
    @Autowired
    private AfterSalesServiceService afterSalesServiceService;
    @Value("${file.upload-dir}")
    private String uploadDir;
    @Override
    public void fileUpload(MultipartFile file, Long afterSalesServiceId) {
        if (file == null || file.isEmpty()) {
            throw new ServiceException("上传文件不能为空");
        }
        if (afterSalesServiceId == null) {
            throw new ServiceException("售后服务ID不能为空");
        }
        AfterSalesService afterSalesService = afterSalesServiceService.getById(afterSalesServiceId);
        if (afterSalesService == null) {
            throw new ServiceException("售后服务记录不存在");
        }
        Long currentTenantId = SecurityUtils.getLoginUser().getTenantId();
        if (!currentTenantId.equals(afterSalesService.getTenantId())) {
            throw new ServiceException("无权操作该售后服务记录");
        }
        try {
            String formalDir = uploadDir + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
            Path formalDirPath = Paths.get(formalDir);
            //  æ­£å¼ç›®å½•存在
            if (!Files.exists(formalDirPath)) {
                Files.createDirectories(formalDirPath);
            }
            //  æ­£å¼æ–‡ä»¶åï¼ˆåŒ…含业务ID + æ—¶é—´æˆ³ + UUID)
            String originalFilename = file.getOriginalFilename();
            String fileExtension = FilenameUtils.getExtension(originalFilename);
            String formalFilename = afterSalesServiceId + "_" +
                    System.currentTimeMillis() + "_" +
                    UUID.randomUUID().toString().substring(0, 8) +
                    (StringUtils.hasText(fileExtension) ? "." + fileExtension : "");
            Path formalFilePath = formalDirPath.resolve(formalFilename);
            file.transferTo(formalFilePath.toFile());
            AfterSalesServiceFile serviceFile = new AfterSalesServiceFile();
            serviceFile.setServiceId(afterSalesServiceId);
            serviceFile.setFileName(originalFilename);
            serviceFile.setFileUrl(formalFilePath.toString());
            serviceFile.setFileSize(file.getSize());
            serviceFile.setFileSuffix(fileExtension);
            serviceFile.setDelFlag("0");
            serviceFile.setCreateUser(SecurityUtils.getUserId());
            serviceFile.setCreateTime(LocalDateTime.now());
            serviceFile.setTenantId(currentTenantId);
            save(serviceFile);
        } catch (Exception e) {
            throw new ServiceException("文件上传失败:" + e.getMessage());
        }
    }
    @Override
    public IPage<AfterSalesServiceFile> fileList(Page<AfterSalesServiceFile> page, Long afterSalesServiceId) {
        if (afterSalesServiceId == null) {
            throw new ServiceException("售后服务ID不能为空");
        }
        LambdaQueryWrapper<AfterSalesServiceFile> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(
                AfterSalesServiceFile::getId,
                AfterSalesServiceFile::getFileName,
                AfterSalesServiceFile::getFileUrl
        );
        wrapper.eq(AfterSalesServiceFile::getServiceId, afterSalesServiceId)
                .eq(AfterSalesServiceFile::getDelFlag, "0")
                .orderByDesc(AfterSalesServiceFile::getCreateTime);
        return page(page, wrapper);
    }
    @Override
    public void delFile(Long fileId) {
        if (fileId == null) {
            throw new ServiceException("附件ID不能为空");
        }
        Long tenantId = SecurityUtils.getLoginUser().getTenantId();
        AfterSalesServiceFile file = getById(fileId);
        if (file == null) {
            throw new ServiceException("附件不存在");
        }
        if (!tenantId.equals(file.getTenantId())) {
            throw new ServiceException("无权限删除");
        }
        removeById(fileId);
        FileUtils.deleteFile(file.getFileUrl());
    }
}
src/main/java/com/ruoyi/approve/controller/ApproveProcessController.java
@@ -21,7 +21,7 @@
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import java.util.*;
@RestController
@RequestMapping("/approveProcess")
@@ -63,8 +63,16 @@
        if (approveProcessVO == null) {
            return AjaxResult.warn("参数不能为空");
        }
        approveProcessService.addApprove(approveProcessVO);
        Set<Long> approveDeptIdSet = Optional.ofNullable(approveProcessVO.getApproveDeptIdArray()).orElse(new HashSet<>());
        approveDeptIdSet.add(approveProcessVO.getApproveDeptId());
        approveDeptIdSet.stream().filter(Objects::nonNull).distinct().forEach(depId->{
            try {
                approveProcessVO.setApproveDeptId(depId);
                approveProcessService.addApprove(approveProcessVO);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        return AjaxResult.success("添加成功");
    }
src/main/java/com/ruoyi/approve/utils/DailyRedisCounter.java
@@ -71,29 +71,33 @@
     * @return ä»Šæ—¥è‡ªå¢žåŽçš„计数值
     */
    public long incrementAndGetByDb() {
        String approveId = redisTemplate.opsForValue().get("approveNum");
        if(approveId == null){
        String key = "approveNumHSXNY";
        // 1. å…ˆå°è¯•从 Redis è‡ªå¢žï¼ˆåŽŸå­æ“ä½œï¼‰
        Long num = redisTemplate.opsForValue().increment(key);
        // 2. å¦‚果是第一次(说明 key ä¸å­˜åœ¨ï¼‰
        if (num == null || num == 1L) {
            // æŸ¥è¯¢æ•°æ®åº“当前最大值(更合理)
            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);
            LambdaQueryWrapper<ApproveProcess> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ApproveProcess::getApproveDelete, 0)
                    .ge(ApproveProcess::getCreateTime, dateTime.getStartDate())
                    .lt(ApproveProcess::getCreateTime, dateTime.getEndDate());
            Long count = approveProcessMapper.selectCount(wrapper);
            long start = (count == null ? 0 : count) + 1;
            // è®¾ç½®åˆå§‹å€¼ï¼ˆé¿å…è¦†ç›–并发)
            redisTemplate.opsForValue().set(key, String.valueOf(start), 1L, TimeUnit.HOURS);
            return start;
        }
        return num;
    }
    /**
src/main/java/com/ruoyi/approve/vo/ApproveProcessVO.java
@@ -11,6 +11,7 @@
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Set;
@Data
public class ApproveProcessVO {
@@ -28,6 +29,9 @@
     * å®¡æ‰¹éƒ¨é—¨id
     */
    private Long approveDeptId;
    private Set<Long> approveDeptIdArray;
    /**
     * å®¡æ‰¹æ—¶é—´
     */
src/main/resources/mapper/aftersalesservice/AfterSalesNearExpiryMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
<?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.aftersalesservice.mapper.AfterSalesNearExpiryMapper">
    <resultMap id="AfterSalesNearExpiryResultMap" type="com.ruoyi.aftersalesservice.pojo.AfterSalesNearExpiry">
        <id property="id" column="id"/>
        <result property="productName" column="product_name"/>
        <result property="batchNumber" column="batch_number"/>
        <result property="expireDate" column="expire_date"/>
        <result property="stockQuantity" column="stock_quantity"/>
        <result property="customerName" column="customer_name"/>
        <result property="contactPhone" column="contact_phone"/>
        <result property="disRes" column="dis_res"/>
        <result property="disposeResult" column="dispose_result"/>
        <result property="status" column="status"/>
        <result property="disposeUserId" column="dispose_user_id"/>
        <result property="disposeNickName" column="dispose_nick_name"/>
        <result property="disDate" column="dis_date"/>
        <result property="createUser" column="create_user"/>
        <result property="createTime" column="create_time"/>
        <result property="updateUser" column="update_user"/>
        <result property="updateTime" column="update_time"/>
        <result property="tenantId" column="tenant_id"/>
    </resultMap>
    <select id="listPage" resultType="com.ruoyi.aftersalesservice.pojo.AfterSalesNearExpiry">
        select * from after_sales_near_expiry
        where 1 = 1
        <if test="req.expireDate != null">
            AND expire_date = #{req.expireDate}
        </if>
        <if test="req.disDate != null">
            AND dis_date = #{req.disDate}
        </if>
        <if test="req.status != null">
            AND status = #{req.status}
        </if>
        order by create_time desc
    </select>
</mapper>
src/main/resources/mapper/aftersalesservice/AfterSalesServiceFileMapper.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.aftersalesservice.mapper.AfterSalesServiceFileMapper">
    <resultMap id="AfterSalesServiceFileResultMap" type="com.ruoyi.aftersalesservice.pojo.AfterSalesServiceFile">
        <id property="id" column="id"/>
        <result property="serviceId" column="service_id"/>
        <result property="fileName" column="file_name"/>
        <result property="fileUrl" column="file_url"/>
        <result property="fileSize" column="file_size"/>
        <result property="fileSuffix" column="file_suffix"/>
        <result property="delFlag" column="del_flag"/>
        <result property="createUser" column="create_user"/>
        <result property="createTime" column="create_time"/>
        <result property="updateUser" column="update_user"/>
        <result property="updateTime" column="update_time"/>
        <result property="tenantId" column="tenant_id"/>
    </resultMap>
</mapper>