From 84746c6a1fe8fb6c0216495110895cb5d346563e Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期二, 03 三月 2026 09:10:24 +0800
Subject: [PATCH] feat: 售后附件与临期售后信息接口

---
 src/main/resources/mapper/aftersalesservice/AfterSalesServiceFileMapper.xml                  |   21 +
 src/main/java/com/ruoyi/aftersalesservice/pojo/AfterSalesServiceFile.java                    |   62 +++++
 src/main/java/com/ruoyi/aftersalesservice/mapper/AfterSalesNearExpiryMapper.java             |   22 +
 src/main/java/com/ruoyi/aftersalesservice/service/AfterSalesServiceFileService.java          |   26 ++
 src/main/java/com/ruoyi/aftersalesservice/pojo/AfterSalesNearExpiry.java                     |   91 +++++++
 src/main/resources/mapper/aftersalesservice/AfterSalesNearExpiryMapper.xml                   |   41 +++
 src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesNearExpiryController.java     |   77 ++++++
 src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesServiceFileController.java    |   56 ++++
 src/main/java/com/ruoyi/aftersalesservice/service/AfterSalesNearExpiryService.java           |   26 ++
 src/main/java/com/ruoyi/aftersalesservice/mapper/AfterSalesServiceFileMapper.java            |   16 +
 src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceFileServiceImpl.java |  137 +++++++++++
 src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesNearExpiryServiceImpl.java  |   89 +++++++
 12 files changed, 664 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesNearExpiryController.java b/src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesNearExpiryController.java
new file mode 100644
index 0000000..69b21c7
--- /dev/null
+++ b/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);
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesServiceFileController.java b/src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesServiceFileController.java
new file mode 100644
index 0000000..4a09c05
--- /dev/null
+++ b/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("鍒犻櫎鎴愬姛!");
+    }
+}
diff --git a/src/main/java/com/ruoyi/aftersalesservice/mapper/AfterSalesNearExpiryMapper.java b/src/main/java/com/ruoyi/aftersalesservice/mapper/AfterSalesNearExpiryMapper.java
new file mode 100644
index 0000000..2cef077
--- /dev/null
+++ b/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);
+
+}
diff --git a/src/main/java/com/ruoyi/aftersalesservice/mapper/AfterSalesServiceFileMapper.java b/src/main/java/com/ruoyi/aftersalesservice/mapper/AfterSalesServiceFileMapper.java
new file mode 100644
index 0000000..fd28cad
--- /dev/null
+++ b/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> {
+}
diff --git a/src/main/java/com/ruoyi/aftersalesservice/pojo/AfterSalesNearExpiry.java b/src/main/java/com/ruoyi/aftersalesservice/pojo/AfterSalesNearExpiry.java
new file mode 100644
index 0000000..d29666d
--- /dev/null
+++ b/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("澶勭悊浜篒D")
+    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;
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/aftersalesservice/pojo/AfterSalesServiceFile.java b/src/main/java/com/ruoyi/aftersalesservice/pojo/AfterSalesServiceFile.java
new file mode 100644
index 0000000..5dcae01
--- /dev/null
+++ b/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浠h〃瀛樺湪 1浠h〃鍒犻櫎锛�")
+    private String delFlag;
+
+    @ApiModelProperty("涓婁紶鑰�")
+    private Long createUser;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("淇敼鑰�")
+    private Long updateUser;
+
+    @ApiModelProperty("淇敼鏃堕棿")
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("绉熸埛id")
+    private Long tenantId;
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/aftersalesservice/service/AfterSalesNearExpiryService.java b/src/main/java/com/ruoyi/aftersalesservice/service/AfterSalesNearExpiryService.java
new file mode 100644
index 0000000..032703d
--- /dev/null
+++ b/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);
+
+}
diff --git a/src/main/java/com/ruoyi/aftersalesservice/service/AfterSalesServiceFileService.java b/src/main/java/com/ruoyi/aftersalesservice/service/AfterSalesServiceFileService.java
new file mode 100644
index 0000000..c1993f1
--- /dev/null
+++ b/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);
+}
diff --git a/src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesNearExpiryServiceImpl.java b/src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesNearExpiryServiceImpl.java
new file mode 100644
index 0000000..d8fc90d
--- /dev/null
+++ b/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);
+    }
+}
diff --git a/src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceFileServiceImpl.java b/src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceFileServiceImpl.java
new file mode 100644
index 0000000..c1e7bd5
--- /dev/null
+++ b/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>
+ * 鍞悗鏈嶅姟闄勪欢琛ㄦ帴鍙e疄鐜扮被
+ * </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);
+            //  姝e紡鐩綍瀛樺湪
+            if (!Files.exists(formalDirPath)) {
+                Files.createDirectories(formalDirPath);
+            }
+            //  姝e紡鏂囦欢鍚嶏紙鍖呭惈涓氬姟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());
+    }
+}
diff --git a/src/main/resources/mapper/aftersalesservice/AfterSalesNearExpiryMapper.xml b/src/main/resources/mapper/aftersalesservice/AfterSalesNearExpiryMapper.xml
new file mode 100644
index 0000000..e4b3c77
--- /dev/null
+++ b/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>
\ No newline at end of file
diff --git a/src/main/resources/mapper/aftersalesservice/AfterSalesServiceFileMapper.xml b/src/main/resources/mapper/aftersalesservice/AfterSalesServiceFileMapper.xml
new file mode 100644
index 0000000..ef5e5a2
--- /dev/null
+++ b/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>
\ No newline at end of file

--
Gitblit v1.9.3