gongchunyi
2026-06-24 d468ff4afaed47caec1217d72763fdc679e7bddc
feat: 新增售后消息推送、售后数量自定义
已修改7个文件
已添加2个文件
110 ■■■■ 文件已修改
doc/after_sales_service_add_column.sql 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesServiceController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/dto/AfterSalesProductDto.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/dto/AfterSalesServiceNewDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/pojo/AfterSalesService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceServiceImpl.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/after_sales_service_add_column.sql
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
ALTER TABLE `after_sales_service` ADD COLUMN `after_sales_products` text COMMENT '售后产品详情';
src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesServiceController.java
@@ -1,5 +1,6 @@
package com.ruoyi.aftersalesservice.controller;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.aftersalesservice.dto.AfterSalesServiceExeclDto;
@@ -97,12 +98,15 @@
    @ApiOperation("售后服务-修改")
    @Log(title = "售后服务-修改", businessType = BusinessType.UPDATE)
    public AjaxResult update(@RequestBody AfterSalesServiceNewDto afterSalesServiceNewDto) {
        if (afterSalesServiceNewDto.getProductModelIdList() != null && afterSalesServiceNewDto.getProductModelIdList().isEmpty() ) {
        if (afterSalesServiceNewDto.getProductModelIdList() != null && !afterSalesServiceNewDto.getProductModelIdList().isEmpty() ) {
            String productModelIds = afterSalesServiceNewDto.getProductModelIdList().stream()
                    .map(String::valueOf)
                    .collect(Collectors.joining(","));
            afterSalesServiceNewDto.setProductModelIds(productModelIds);
        }
        if (afterSalesServiceNewDto.getAfterSalesProductList() != null && !afterSalesServiceNewDto.getAfterSalesProductList().isEmpty()) {
            afterSalesServiceNewDto.setAfterSalesProducts(JSON.toJSONString(afterSalesServiceNewDto.getAfterSalesProductList()));
        }
        boolean update = afterSalesServiceService.updateById(afterSalesServiceNewDto);
        return update ? AjaxResult.success() : AjaxResult.error();
    }
src/main/java/com/ruoyi/aftersalesservice/dto/AfterSalesProductDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
package com.ruoyi.aftersalesservice.dto;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class AfterSalesProductDto {
    private Long id;
    private BigDecimal afterSalesQuantity;
}
src/main/java/com/ruoyi/aftersalesservice/dto/AfterSalesServiceNewDto.java
@@ -17,6 +17,9 @@
    @ApiModelProperty("产品型号ID数组")
    private List<Long> productModelIdList;
    @ApiModelProperty("售后产品详情列表")
    private List<AfterSalesProductDto> afterSalesProductList;
    private SalesLedgerDto salesLedgerDto;
    private String salesContractNo;
src/main/java/com/ruoyi/aftersalesservice/pojo/AfterSalesService.java
@@ -158,6 +158,7 @@
    @ApiModelProperty("产品型号IDs")
    private String productModelIds;
    @ApiModelProperty("售后产品详情")
    private String afterSalesProducts;
}
src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceServiceImpl.java
@@ -1,5 +1,6 @@
package com.ruoyi.aftersalesservice.service.impl;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -16,6 +17,7 @@
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysDeptMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.project.system.service.ISysNoticeService;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
@@ -27,6 +29,7 @@
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@@ -50,6 +53,8 @@
    private ISalesLedgerProductService salesLedgerProductService;
    @Autowired
    private ISalesLedgerService salesLedgerService;
    @Autowired
    private ISysNoticeService sysNoticeService;
    @Override
    public IPage<AfterSalesServiceNewDto> listPage(Page page, AfterSalesServiceNewDto afterSalesService) {
@@ -65,11 +70,14 @@
    @Override
    public boolean addAfterSalesServiceDto(AfterSalesServiceNewDto afterSalesServiceNewDto) {
        afterSalesServiceNewDto.setStatus(1);
        if (afterSalesServiceNewDto.getProductModelIdList() != null && afterSalesServiceNewDto.getProductModelIdList().isEmpty() ) {
        if (afterSalesServiceNewDto.getProductModelIdList() != null && !afterSalesServiceNewDto.getProductModelIdList().isEmpty() ) {
            String productModelIds = afterSalesServiceNewDto.getProductModelIdList().stream()
                    .map(String::valueOf)
                    .collect(Collectors.joining(","));
            afterSalesServiceNewDto.setProductModelIds(productModelIds);
        }
        if (afterSalesServiceNewDto.getAfterSalesProductList() != null && !afterSalesServiceNewDto.getAfterSalesProductList().isEmpty()) {
            afterSalesServiceNewDto.setAfterSalesProducts(JSON.toJSONString(afterSalesServiceNewDto.getAfterSalesProductList()));
        }
        SysUser sysUser = sysUserMapper.selectUserById(afterSalesServiceNewDto.getCheckUserId());
        if(sysUser == null) throw new RuntimeException("审核人不存在");
@@ -78,7 +86,26 @@
            String string = OrderUtils.countAfterServiceTodayByCreateTime(afterSalesServiceMapper, "SH_");
            afterSalesServiceNewDto.setAfterSalesServiceNo(string);
        }
        return this.save(afterSalesServiceNewDto);
        boolean saved = this.save(afterSalesServiceNewDto);
        if (saved && afterSalesServiceNewDto.getSalesLedgerId() != null) {
            try {
                SalesLedger salesLedger = salesLedgerService.getById(afterSalesServiceNewDto.getSalesLedgerId());
                if (salesLedger != null && StringUtils.isNotEmpty(salesLedger.getEntryPerson())) {
                    Long entryUserId = Long.parseLong(salesLedger.getEntryPerson());
                    String webPath = "/customerService/afterSalesHandling?afterSalesServiceNo=" + afterSalesServiceNewDto.getAfterSalesServiceNo();
                    sysNoticeService.simpleNoticeByUser(
                        "新增售后单通知",
                        "您录入的销售订单有一条新的售后记录,售后单号:" + afterSalesServiceNewDto.getAfterSalesServiceNo(),
                        Collections.singletonList(entryUserId),
                        webPath
                    );
                }
            } catch (Exception e) {
                log.error("发送售后新增通知失败: ", e);
            }
        }
        return saved;
    }
    @Override
@@ -87,6 +114,19 @@
        SalesLedger byId = salesLedgerService.getById(afterSalesService.getSalesLedgerId());
        List<Long> collect = Arrays.stream(afterSalesService.getProductModelIds().split(",")).map(Long::valueOf).collect(Collectors.toList());
        List<SalesLedgerProduct> list = salesLedgerProductService.list(new QueryWrapper<SalesLedgerProduct>().lambda().in(SalesLedgerProduct::getId, collect));
        if (StringUtils.isNotEmpty(afterSalesService.getAfterSalesProducts())) {
            List<com.ruoyi.aftersalesservice.dto.AfterSalesProductDto> afterSalesProductList = com.alibaba.fastjson2.JSON.parseArray(afterSalesService.getAfterSalesProducts(), com.ruoyi.aftersalesservice.dto.AfterSalesProductDto.class);
            for (SalesLedgerProduct product : list) {
                for (com.ruoyi.aftersalesservice.dto.AfterSalesProductDto productDto : afterSalesProductList) {
                    if (product.getId().equals(productDto.getId())) {
                        product.setAfterSalesQuantity(productDto.getAfterSalesQuantity());
                        break;
                    }
                }
            }
        }
        AfterSalesServiceNewDto afterSalesServiceNewDto = new AfterSalesServiceNewDto();
        BeanUtils.copyProperties(afterSalesService, afterSalesServiceNewDto);
        SalesLedgerDto salesLedgerDto = new SalesLedgerDto();
src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
@@ -152,11 +152,11 @@
                .map(it -> convertSysNotice(title, message, it, tenantId, jumpPath, unipushService.convertWebPathToAppPath(jumpPath), userId))
                .collect(Collectors.toList());
        sysNoticeService.saveBatch(sysNotices);
//        try {
//            unipushService.sendClientMessage(sysNotices);
//        } catch (Exception e) {
//            log.error("APP推送通知失败,原因: {}", e);
//        }
        try {
            unipushService.sendClientMessage(sysNotices);
        } catch (Exception e) {
            log.error("APP推送通知失败,原因: {}", e);
        }
    }
    @Override
@@ -209,11 +209,11 @@
                .collect(Collectors.toList());
        sysNoticeService.saveBatch(collect);
//        try {
//            unipushService.sendClientMessage(collect);
//        } catch (Exception e) {
//            log.error("APP推送通知失败,原因: {}", e);
//        }
        try {
            unipushService.sendClientMessage(collect);
        } catch (Exception e) {
            log.error("APP推送通知失败,原因: {}", e);
        }
    }
src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java
@@ -146,6 +146,26 @@
    }
    /**
     * å‘送直接路由推送(不经过SysNotice表)
     */
    public void sendDirectRoutingPushToUser(Long userId, String title, String content, String webPath) {
        SysUserClient client = userClientService.getById(userId);
        if (client == null || StringUtils.isEmpty(client.getCid())) {
            log.warn("用户 {} æœªç»‘定移动端 CID,跳过直接推送", userId);
            return;
        }
        String appPath = convertWebPathToAppPath(webPath);
        sendRoutingPush(
                System.currentTimeMillis(),
                client.getCid(),
                title,
                content,
                appPath,
                false
        );
    }
    /**
     * å‘送单人路由推送
     */
    private void sendRoutingPush(Long noticeId, String cid, String title, String content, String targetPath) {
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -351,6 +351,9 @@
    @TableField(exist = false)
    private BigDecimal availableQuality;
    @TableField(exist = false)
    @ApiModelProperty("售后数量")
    private BigDecimal afterSalesQuantity;
    public void fillRemainingQuantity() {
        BigDecimal q = this.quantity == null ? BigDecimal.ZERO : this.quantity;