liyong
2026-04-30 a6ff41048bbdd5b8519a3e21e9232a152d179dfc
Merge remote-tracking branch 'origin/dev_New' into dev_New
已添加6个文件
已修改32个文件
已删除14个文件
1942 ■■■■■ 文件已修改
doc/create_table_customer_user.sql 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/pojo/AccountIncome.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/impl/AccountIncomeServiceImpl.java 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/controller/CustomerController.java 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/controller/CustomerFollowUpController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/controller/CustomerPrivateController.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/controller/CustomerPrivatePoolController.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/dto/CustomerDto.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/dto/CustomerPrivateDto.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/dto/CustomerPrivatePoolDto.java 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/mapper/CustomerMapper.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/mapper/CustomerPrivateMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/mapper/CustomerPrivatePoolMapper.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/mapper/CustomerUserMapper.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/Customer.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/CustomerPrivate.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/CustomerPrivatePool.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/CustomerUser.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/CustomerPrivatePoolService.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/CustomerPrivateService.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/CustomerUserService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/ICustomerService.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerFollowUpServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerPrivatePoolServiceImpl.java 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerPrivateServiceImpl.java 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerReturnVisitServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java 178 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerUserServiceImpl.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/task/ReturnVisitReminderTask.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/vo/CustomerVo.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/service/impl/InspectionTaskServiceImpl.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/PaymentRegistrationServiceImpl.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesLedgerProductDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesQuotation.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/ReceiptPaymentServiceImpl.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/account/AccountIncomeMapper.xml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/basic/CustomerMapper.xml 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/basic/CustomerPrivateMapper.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/basic/CustomerPrivatePoolMapper.xml 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/purchase/PaymentRegistrationMapper.xml 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/InvoiceLedgerMapper.xml 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/ReceiptPaymentMapper.xml 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesQuotationMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/create_table_customer_user.sql
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
drop table if exists customer_user;
create table customer_user
(
    id          bigint auto_increment
        primary key,
    customer_id bigint not null default 0 comment '客户id',
    user_id     bigint not null default 0 comment '用户id',
    create_time datetime null comment '录入时间',
    tenant_id   bigint not null default 0 comment '租户id'
);
src/main/java/com/ruoyi/account/pojo/AccountIncome.java
@@ -13,6 +13,7 @@
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
/**
 * è´¢åŠ¡ç®¡ç†--收入管理
@@ -20,7 +21,7 @@
 */
@TableName(value = "account_income")
@Data
public class AccountIncome extends DateQueryDto  implements Serializable {
public class AccountIncome extends DateQueryDto implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
@@ -50,7 +51,7 @@
    /**
     * æ”¶å…¥ç±»åž‹(销售收入,服务收入,其他收入)
     */
    @Excel(name = "收入类型",readConverterExp = "0=销售收入,1=服务收入,2=其他收入,3=回款收入")
    @Excel(name = "收入类型", readConverterExp = "0=销售收入,1=服务收入,2=其他收入,3=回款收入")
    @NotBlank(message = "收入类型不能为空!!")
    private String incomeType;
@@ -75,10 +76,28 @@
    /**
     * æ”¶æ¬¾æ–¹å¼(现金,支票,银行转账,其他)
     */
    @Excel(name = "收款方式",readConverterExp = "0=现金,1=支票,2=银行转账,3=其他")
    @Excel(name = "收款方式", readConverterExp = "0=现金,1=支票,2=银行转账,3=其他")
    private String incomeMethod;
    /**
     * æ”¶æ¬¾æ–¹å¼æ ‡ç­¾
     */
    @TableField(exist = false)
    private String incomeMethodLabel;
    /**
     * payment_methods å­—典编码集合(business_type ä¸ºç©ºæ—¶ï¼‰
     */
    @TableField(exist = false)
    private List<String> paymentMethodList;
    /**
     * receipt_payment_type å­—典编码集合(business_type=1时)
     */
    @TableField(exist = false)
    private List<String> receiptPaymentMethodList;
    /**
     * å‘票号码
     */
    @Excel(name = "发票号码")
src/main/java/com/ruoyi/account/service/impl/AccountIncomeServiceImpl.java
@@ -5,13 +5,11 @@
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.account.dto.AccountDto2;
import com.ruoyi.account.dto.AccountDto3;
import com.ruoyi.account.dto.ReportDateDto;
import com.ruoyi.account.mapper.AccountIncomeMapper;
import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.account.service.AccountIncomeService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.dto.DateQueryDto;
import com.ruoyi.project.system.domain.SysDictData;
@@ -24,9 +22,9 @@
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@AllArgsConstructor
@Service
@@ -40,9 +38,40 @@
    //分页查询
    @Override
    public IPage<AccountIncome> accountIncomeListPage(Page page, AccountIncome accountIncome) {
        resolveIncomeMethodLabelFilter(accountIncome);
        return accountIncomeMapper.accountIncomeListPage(page,accountIncome);
    }
    private void resolveIncomeMethodLabelFilter(AccountIncome accountIncome) {
        if (accountIncome == null) {
            return;
        }
        if (accountIncome.getIncomeMethodLabel() == null || accountIncome.getIncomeMethodLabel().trim().isEmpty()) {
            return;
        }
        String targetLabel = accountIncome.getIncomeMethodLabel().trim();
        List<String> paymentMethodList = selectDictValuesByLabel("payment_methods", targetLabel);
        List<String> receiptPaymentMethodList = selectDictValuesByLabel("receipt_payment_type", targetLabel);
        if (paymentMethodList.isEmpty()) {
            paymentMethodList = Collections.singletonList("__NO_MATCH__");
        }
        if (receiptPaymentMethodList.isEmpty()) {
            receiptPaymentMethodList = Collections.singletonList("__NO_MATCH__");
        }
        accountIncome.setPaymentMethodList(paymentMethodList);
        accountIncome.setReceiptPaymentMethodList(receiptPaymentMethodList);
        accountIncome.setIncomeMethod(null);
    }
    private List<String> selectDictValuesByLabel(String dictType, String label) {
        return sysDictDataMapper.selectDictDataByType(dictType).stream()
                .filter(item -> label.equals(item.getDictLabel()))
                .map(SysDictData::getDictValue)
                .filter(v -> v != null && !v.trim().isEmpty())
                .distinct()
                .collect(Collectors.toList());
    }
    //导出
    @Override
    public void accountIncomeExport(HttpServletResponse response, AccountIncome accountIncome) {
src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
@@ -10,9 +10,11 @@
import com.ruoyi.approve.bean.vo.ApproveProcessConfigNodeVo;
import com.ruoyi.approve.bean.vo.ApproveProcessVO;
import com.ruoyi.approve.mapper.ApproveNodeMapper;
import com.ruoyi.approve.mapper.ApproveProcessConfigNodeMapper;
import com.ruoyi.approve.mapper.ApproveProcessMapper;
import com.ruoyi.approve.pojo.ApproveNode;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.pojo.ApproveProcessConfigNode;
import com.ruoyi.approve.service.ApproveProcessConfigNodeService;
import com.ruoyi.approve.service.IApproveNodeService;
import com.ruoyi.approve.service.IApproveProcessService;
@@ -63,6 +65,7 @@
    private final ShippingInfoMapper shippingInfoMapper;
    private final ApproveNodeMapper approveNodeMapper;
    private final ApproveProcessConfigNodeService approveProcessConfigNodeService;
    private final ApproveProcessConfigNodeMapper approveProcessConfigNodeMapper;
    @Override
    public void addApprove(ApproveProcessVO approveProcessVO) throws Exception {
@@ -299,16 +302,18 @@
                .last("limit 1");
        ApproveProcess approveProcess = approveProcessMapper.selectOne(approveProcessLambdaQueryWrapper);
        if (approveProcess == null) throw new RuntimeException("请选择审批人");
        String[] split = approveGetAndUpdateVo.getApproveUserIds().split(",");
        if (split.length == 0) {
            throw new RuntimeException("请选择审批人");
        }
        List<SysUser> sysUsers = sysUserMapper.selectUserByIds(Arrays.asList(split).stream().map(Long::parseLong).collect(Collectors.toList()));
        //查询审批配置
        List<ApproveProcessConfigNode> approveProcessConfig = approveProcessConfigNodeMapper.selectList(new LambdaQueryWrapper<ApproveProcessConfigNode>().eq(ApproveProcessConfigNode::getApproveType, approveGetAndUpdateVo.getApproveType()));
        List<Long> configNodeIds = approveProcessConfig.stream()
                .sorted(Comparator.comparing(ApproveProcessConfigNode::getNodeOrder))
                .map(ApproveProcessConfigNode::getApproverId)
                .collect(Collectors.toList());
        List<SysUser> sysUsers = sysUserMapper.selectUserByIds(configNodeIds);
        if (CollectionUtils.isEmpty(sysUsers)) throw new RuntimeException("请选择审批人");
        //审核中不可以编辑审核人
        if (approveProcess.getApproveStatus() != 1) {
            approveProcess.setApproveUserCurrentId(Long.parseLong(split[0]));
            approveProcess.setApproveUserCurrentName(sysUsers.stream().filter(user -> user.getUserId().equals(Long.parseLong(split[0]))).collect(Collectors.toList()).get(0).getNickName());
            approveProcess.setApproveUserCurrentId(configNodeIds.get(0));
            approveProcess.setApproveUserCurrentName(sysUsers.stream().filter(user -> user.getUserId().equals(configNodeIds.get(0))).collect(Collectors.toList()).get(0).getNickName());
        }
        if (approveGetAndUpdateVo.getApproveStatus() != null) {
            approveProcess.setApproveStatus(approveGetAndUpdateVo.getApproveStatus());
@@ -320,21 +325,24 @@
        LambdaQueryWrapper<ApproveNode> approveNodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        approveNodeLambdaQueryWrapper.eq(ApproveNode::getApproveProcessId, approveProcess.getApproveId())
                .eq(ApproveNode::getDeleteFlag, 0)
//                .eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                .orderByAsc(ApproveNode::getApproveNodeOrder);
        approveNodeMapper.delete(approveNodeLambdaQueryWrapper);
        //查询审批配置
        approveGetAndUpdateVo.setApproveUserIds(configNodeIds.stream()
                .map(String::valueOf)
                .collect(Collectors.joining(",")));
        approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(), approveProcess.getApproveId(), approveProcess.getTenantId());
        /*消息通知*/
        String id = approveProcess.getApproveUserIds().split(",")[0];
        Long id = configNodeIds.get(0);
        if (approveProcess.getApproveType()==8){
            sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                    approveProcess.getApproveId() + "流程编号的审批需要您审核!!!!!",
                    Arrays.asList(Long.valueOf(id)),
                    Collections.singletonList(id),
                    "/safeProduction/safeWorkApproval?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
        }else {
            sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                    approveProcess.getApproveId() + "流程编号的审批需要您审核!!!!!",
                    Arrays.asList(Long.valueOf(id)),
                    Collections.singletonList(id),
                    "/collaborativeApproval/approvalProcess?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
        }
    }
src/main/java/com/ruoyi/basic/controller/CustomerController.java
@@ -5,6 +5,7 @@
import com.ruoyi.basic.dto.CustomerDto;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.service.ICustomerService;
import com.ruoyi.basic.vo.CustomerVo;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
@@ -35,7 +36,7 @@
     */
    @GetMapping("/list")
    public R list(Page<CustomerDto> page, CustomerDto customer) {
        IPage<CustomerDto> customerDtoIPage = customerService.selectCustomerList(page, customer);
        IPage<CustomerVo> customerDtoIPage = customerService.selectCustomerList(page, customer);
        return R.ok(customerDtoIPage);
    }
@@ -44,16 +45,9 @@
     */
    @Log(title = "客户档案", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Customer customer) {
        Long[] ids = customer.getIds();
        List<Customer> list;
        if (ids != null && ids.length > 0) {
            list = customerService.selectCustomerListByIds(ids);
        } else {
            list = customerService.selectCustomerLists(customer);
        }
        ExcelUtil<Customer> util = new ExcelUtil<Customer>(Customer.class);
        util.exportExcel(response, list, "客户档案数据");
    public void export(HttpServletResponse response, CustomerDto customer) {
        ExcelUtil<CustomerVo> util = new ExcelUtil<CustomerVo>(CustomerVo.class);
        util.exportExcel(response, customerService.selectCustomerLists(customer), "客户档案数据");
    }
    @PostMapping("/downloadTemplate")
@@ -69,9 +63,9 @@
     */
    @Log(title = "客户档案", businessType = BusinessType.IMPORT)
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file) throws Exception {
    public AjaxResult importData(MultipartFile file, Integer type) throws Exception {
        return customerService.importData(file);
        return customerService.importData(file, type);
    }
    /**
@@ -121,4 +115,33 @@
    }
}
    /**
     * åˆ†é…å®¢æˆ·
     */
    @Log(title = "客户档案", businessType = BusinessType.OTHER)
    @PostMapping("/assignCustomer")
    public AjaxResult assignCustomer(@RequestBody CustomerDto customer) {
        customerService.assignCustomer(customer);
        return AjaxResult.success();
    }
    /**
     * å›žæ”¶å®¢æˆ·
     */
    @Log(title = "客户档案", businessType = BusinessType.OTHER)
    @PostMapping("/recycleCustomer")
    public AjaxResult recycleCustomer(@RequestBody CustomerDto customer) {
        customerService.recycleCustomer(customer);
        return AjaxResult.success();
    }
    /**
     * å…±äº«å®¢æˆ·
     */
    @Log(title = "客户档案", businessType = BusinessType.OTHER)
    @PostMapping("/together")
    public AjaxResult together(@RequestBody CustomerDto customer) {
        customerService.together(customer);
        return AjaxResult.success();
    }
}
src/main/java/com/ruoyi/basic/controller/CustomerFollowUpController.java
@@ -46,7 +46,7 @@
    @ApiOperation("查询客户跟进列表")
    public IPage<CustomerFollowUp> list(Page<CustomerFollowUp> page, CustomerFollowUp customerFollowUp) {
        LambdaQueryWrapper<CustomerFollowUp> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(customerFollowUp.getCustomerPrivatePoolId() != null, CustomerFollowUp::getCustomerPrivatePoolId, customerFollowUp.getCustomerPrivatePoolId())
        queryWrapper.eq(customerFollowUp.getCustomerId() != null, CustomerFollowUp::getCustomerId, customerFollowUp.getCustomerId())
                .like(customerFollowUp.getFollowerUserName() != null, CustomerFollowUp::getFollowerUserName, customerFollowUp.getFollowerUserName())
                .orderByDesc(CustomerFollowUp::getFollowUpTime);
        return customerFollowUpService.page(page, queryWrapper);
src/main/java/com/ruoyi/basic/controller/CustomerPrivateController.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/basic/controller/CustomerPrivatePoolController.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/basic/dto/CustomerDto.java
@@ -25,4 +25,8 @@
    private String togetherUserNames;
}
    /**
     * å…±äº«ç”¨æˆ·ID列表
     */
    private List<Long> userIds;
}
src/main/java/com/ruoyi/basic/dto/CustomerPrivateDto.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/basic/dto/CustomerPrivatePoolDto.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/basic/mapper/CustomerMapper.java
@@ -5,6 +5,7 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basic.dto.CustomerDto;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.vo.CustomerVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -67,5 +68,7 @@
     */
    int deleteCustomerByIds(Long[] ids);
    IPage<CustomerDto> listPage(Page<CustomerDto> page, @Param("c") CustomerDto customer);
}
    IPage<CustomerVo> listPage(Page<CustomerDto> page, @Param("c") CustomerDto customer, @Param("loginUserId") Long loginUserId);
    List<CustomerVo> list(@Param("c") CustomerDto customer, @Param("loginUserId") Long loginUserId);
}
src/main/java/com/ruoyi/basic/mapper/CustomerPrivateMapper.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/basic/mapper/CustomerPrivatePoolMapper.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/basic/mapper/CustomerUserMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.ruoyi.basic.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.basic.pojo.CustomerUser;
import org.apache.ibatis.annotations.Mapper;
/**
 * å®¢æˆ·å…±äº«Mapper接口
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @date 2026-04-29
 */
@Mapper
public interface CustomerUserMapper extends BaseMapper<CustomerUser> {
}
src/main/java/com/ruoyi/basic/pojo/Customer.java
@@ -129,4 +129,9 @@
    @ApiModelProperty(value = "使用状态")
    private Long usageStatus;
    @ApiModelProperty(value = "类型 0 ç§æµ·å®¢æˆ· 1 å…¬æµ·å®¢æˆ·")
    private Integer type;
    @ApiModelProperty(value = "是否被分配:0-未分配,1-已分配")
    private Integer isAssigned;
}
src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java
@@ -37,7 +37,7 @@
    /**
     * å…³è”的私海id
     */
    private Long customerPrivatePoolId;
    private Long customerId;
    /**
     * è·Ÿè¿›æ–¹å¼
src/main/java/com/ruoyi/basic/pojo/CustomerPrivate.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/basic/pojo/CustomerPrivatePool.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java
@@ -36,7 +36,7 @@
    /**
     * å…³è”客户ID
     */
    private Integer customerPrivatePoolId;
    private Long customerId;
    /**
     * æé†’开关 (0:关闭, 1:开启)
src/main/java/com/ruoyi/basic/pojo/CustomerUser.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package com.ruoyi.basic.pojo;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
@TableName(value = "customer_user")
@Data
public class CustomerUser implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * åºå·
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * å®¢æˆ·id
     */
    private Long customerId;
    /**
     * ç”¨æˆ·id
     */
    private Long userId;
    /**
     * ç§Ÿæˆ·id
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    /**
     * å½•入时间
     */
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
}
src/main/java/com/ruoyi/basic/service/CustomerPrivatePoolService.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/basic/service/CustomerPrivateService.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/basic/service/CustomerUserService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.ruoyi.basic.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.basic.pojo.CustomerUser;
/**
 * å®¢æˆ·å…±äº«Service接口
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @date 2026-04-29
 */
public interface CustomerUserService extends IService<CustomerUser> {
}
src/main/java/com/ruoyi/basic/service/ICustomerService.java
@@ -4,8 +4,8 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.basic.dto.CustomerDto;
import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.vo.CustomerVo;
import com.ruoyi.framework.web.domain.AjaxResult;
import org.springframework.web.multipart.MultipartFile;
@@ -33,7 +33,7 @@
     * @param id å®¢æˆ·æ¡£æ¡ˆä¸»é”®
     * @return å®¢æˆ·è¯¦æƒ…DTO
     */
    Customer selectCustomerDetailById(Long id);
    CustomerVo selectCustomerDetailById(Long id);
    /**
     * æŸ¥è¯¢å®¢æˆ·æ¡£æ¡ˆåˆ—表
@@ -75,9 +75,20 @@
     */
    List<Map<String, Object>> customerList(Customer customer);
    List<Customer> selectCustomerLists(Customer customer);
    List<CustomerVo> selectCustomerLists(CustomerDto customer);
    AjaxResult importData(MultipartFile file);
    AjaxResult importData(MultipartFile file, Integer type);
    IPage<CustomerDto> selectCustomerList(Page<CustomerDto> page, CustomerDto customer);
}
    IPage<CustomerVo> selectCustomerList(Page<CustomerDto> page, CustomerDto customer);
    void assignCustomer(CustomerDto customer);
    void recycleCustomer(CustomerDto customer);
    /**
     * å…±äº«å®¢æˆ·ç»™å…¶ä»–用户
     *
     * @param customerDto å®¢æˆ·DTO(包含客户ID和共享用户ID列表)
     */
    void together(CustomerDto customerDto);
}
src/main/java/com/ruoyi/basic/service/impl/CustomerFollowUpServiceImpl.java
@@ -132,7 +132,7 @@
        }
        List<CustomerFollowUp> followUps = list(new LambdaQueryWrapper<CustomerFollowUp>()
                .eq(CustomerFollowUp::getCustomerPrivatePoolId, customerId));
                .eq(CustomerFollowUp::getCustomerId, customerId));
        if (followUps != null && !followUps.isEmpty()) {
            for (CustomerFollowUp followUp : followUps) {
src/main/java/com/ruoyi/basic/service/impl/CustomerPrivatePoolServiceImpl.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/basic/service/impl/CustomerPrivateServiceImpl.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/basic/service/impl/CustomerReturnVisitServiceImpl.java
@@ -75,7 +75,7 @@
            throw new ServiceException("客户ID不能为空");
        }
        LambdaQueryWrapper<CustomerReturnVisit> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CustomerReturnVisit::getCustomerPrivatePoolId, customerId);
        queryWrapper.eq(CustomerReturnVisit::getCustomerId, customerId);
        CustomerReturnVisit returnVisit = baseMapper.selectOne(queryWrapper);
        if (returnVisit == null) {
@@ -94,7 +94,7 @@
            throw new ServiceException("客户ID不能为空");
        }
        LambdaQueryWrapper<CustomerReturnVisit> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CustomerReturnVisit::getCustomerPrivatePoolId, customerId);
        queryWrapper.eq(CustomerReturnVisit::getCustomerId, customerId);
        List<CustomerReturnVisit> returnVisits = baseMapper.selectList(queryWrapper);
        for (CustomerReturnVisit returnVisit : returnVisits) {
@@ -124,7 +124,7 @@
        if (returnVisit == null) {
            throw new ServiceException("回访提醒数据不能为空");
        }
        if (returnVisit.getCustomerPrivatePoolId() == null) {
        if (returnVisit.getCustomerId() == null) {
            throw new ServiceException("客户ID不能为空");
        }
        if (returnVisit.getReminderTime() == null) {
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -9,23 +9,19 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.dto.CustomerDto;
import com.ruoyi.basic.dto.CustomerFollowUpDto;
import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
import com.ruoyi.basic.mapper.CustomerMapper;
import com.ruoyi.basic.mapper.CustomerPrivatePoolMapper;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.pojo.CustomerFollowUp;
import com.ruoyi.basic.pojo.CustomerFollowUpFile;
import com.ruoyi.basic.pojo.CustomerPrivatePool;
import com.ruoyi.basic.pojo.*;
import com.ruoyi.basic.service.CustomerFollowUpFileService;
import com.ruoyi.basic.service.CustomerFollowUpService;
import com.ruoyi.basic.service.CustomerReturnVisitService;
import com.ruoyi.basic.service.CustomerUserService;
import com.ruoyi.basic.service.ICustomerService;
import com.ruoyi.basic.vo.CustomerVo;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.pojo.SalesLedger;
import lombok.AllArgsConstructor;
@@ -37,7 +33,6 @@
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;
@@ -56,8 +51,6 @@
    @Autowired
    private  SalesLedgerMapper salesLedgerMapper;
    @Autowired
    private CustomerPrivatePoolMapper customerPrivatePoolMapper;
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
@@ -66,6 +59,8 @@
    private CustomerFollowUpFileService customerFollowUpFileService;
    @Autowired
    private CustomerReturnVisitService customerReturnVisitService;
    @Autowired
    private CustomerUserService customerUserService;
    /**
     * æŸ¥è¯¢å®¢æˆ·æ¡£æ¡ˆ
@@ -85,8 +80,35 @@
     * @return å®¢æˆ·è¯¦æƒ…DTO
     */
    @Override
    public Customer selectCustomerDetailById(Long id) {
        return this.getById( id);
    public CustomerVo selectCustomerDetailById(Long id) {
        CustomerVo customerVo = new CustomerVo();
        BeanUtils.copyProperties(this.getById(id), customerVo);
        // æŸ¥è¯¢è·Ÿè¿›è®°å½•
        List<CustomerFollowUp> followUpList = customerFollowUpService.list(
                new LambdaQueryWrapper<CustomerFollowUp>()
                        .eq(CustomerFollowUp::getCustomerId, id)
                        .orderByDesc(CustomerFollowUp::getFollowUpTime)
        );
        if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(followUpList)) {
            List<CustomerFollowUpDto> followUpDtoList = followUpList.stream().map(followUp -> {
                CustomerFollowUpDto followUpDto = new CustomerFollowUpDto();
                BeanUtils.copyProperties(followUp, followUpDto);
                // æŸ¥è¯¢é™„ä»¶
                List<CustomerFollowUpFile> fileList = customerFollowUpFileService.list(
                        new LambdaQueryWrapper<CustomerFollowUpFile>()
                                .eq(CustomerFollowUpFile::getFollowUpId, followUp.getId())
                );
                followUpDto.setFileList(fileList);
                return followUpDto;
            }).collect(Collectors.toList());
            customerVo.setFollowUpList(followUpDtoList);
        }
        return customerVo;
    }
    /**
@@ -96,16 +118,18 @@
     * @return å®¢æˆ·æ¡£æ¡ˆ
     */
    @Override
    public IPage<CustomerDto> selectCustomerList(Page<CustomerDto> page, CustomerDto customer) {
        IPage<CustomerDto> customerPage = customerMapper.listPage(page, customer);
    public IPage<CustomerVo> selectCustomerList(Page<CustomerDto> page, CustomerDto customer) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long loginUserId = loginUser.getUserId();
        IPage<CustomerVo> customerPage = customerMapper.listPage(page, customer, loginUserId);
        List<CustomerDto> records = customerPage.getRecords();
        List<CustomerVo> records = customerPage.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return customerPage;
        }
        List<Long> customerIds = records.stream()
                .map(CustomerDto::getId)
                .map(CustomerVo::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
@@ -124,6 +148,16 @@
                            followUp.getFollowUpTime().atZone(ZoneId.systemDefault()).toInstant()
                    ));
                }
                // è½¬æ¢å…±äº«ç”¨æˆ·ID字符串为List<Long>
                String userIdsStr = c.getUserIdsStr();
                if (StringUtils.isNotEmpty(userIdsStr)) {
                    List<Long> userIds = Arrays.stream(userIdsStr.split(","))
                            .map(String::trim)
                            .map(Long::parseLong)
                            .collect(Collectors.toList());
                    c.setUserIds(userIds);
                }
            });
        }
@@ -133,13 +167,13 @@
    private Map<Long, CustomerFollowUp> getLatestFollowUpMap(List<Long> customerIds) {
        List<CustomerFollowUp> followUps = customerFollowUpService.list(
                new LambdaQueryWrapper<CustomerFollowUp>()
                        .in(CustomerFollowUp::getCustomerPrivatePoolId, customerIds)
                        .in(CustomerFollowUp::getCustomerId, customerIds)
                        .orderByDesc(CustomerFollowUp::getFollowUpTime)
        );
        return followUps.stream()
                .collect(Collectors.toMap(
                        CustomerFollowUp::getCustomerPrivatePoolId,
                        CustomerFollowUp::getCustomerId,
                        followUp -> followUp,
                        (existing, replacement) -> existing
                ));
@@ -187,16 +221,28 @@
        if (!salesLedgers.isEmpty()) {
            throw new RuntimeException("客户档案下有销售合同,请先删除销售合同");
        }
        List<CustomerPrivatePool> customerPrivatePools = customerPrivatePoolMapper.selectList(new QueryWrapper<CustomerPrivatePool>().lambda().in(CustomerPrivatePool::getCustomerId, idList));
        if (!customerPrivatePools.isEmpty()) {
            throw new RuntimeException("客户档案下有客户私海,请先收回私海数据");
        // æŸ¥è¯¢æ˜¯å¦æœ‰å·²åˆ†é…çš„公海客户
        List<Customer> assignedPools = customerMapper.selectList(
                new QueryWrapper<Customer>().lambda()
                        .in(Customer::getId, idList)
                        .eq(Customer::getType, 1).
                        eq(Customer::getIsAssigned, 1)  // å…¬æµ·å®¢æˆ·
        );
        if (!assignedPools.isEmpty()) {
            throw new RuntimeException("客户档案下有已分配的公海客户,请先收回");
        }
        //  åˆ é™¤å®¢æˆ·çš„同时也需要删除对应的客户跟随、附件和回访提醒
        // åˆ é™¤å®¢æˆ·çš„同时也需要删除对应的客户跟随、附件和回访提醒
        for (Long id : ids) {
            customerFollowUpService.deleteByCustomerId(id);
            customerReturnVisitService.deleteByCustomerId(id);
            // åˆ é™¤å®¢æˆ·çš„共享关系
            customerUserService.remove(
                new QueryWrapper<CustomerUser>().lambda()
                    .eq(CustomerUser::getCustomerId, id)
            );
        }
        // åˆ é™¤å®¢æˆ·ä¸»è¡¨æ•°æ®
        return customerMapper.deleteBatchIds(idList);
    }
@@ -208,17 +254,26 @@
    }
    @Override
    public List<Customer> selectCustomerLists(Customer customer) {
        return customerMapper.selectList(null);
    public List<CustomerVo> selectCustomerLists(CustomerDto customer) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long loginUserId = loginUser.getUserId();
        return customerMapper.list(customer, loginUserId);
    }
    @Override
    public AjaxResult importData(MultipartFile file) {
    public AjaxResult importData(MultipartFile file, Integer type) {
        try {
            ExcelUtil<Customer> util = new ExcelUtil<Customer>(Customer.class);
            List<Customer> userList = util.importExcel(file.getInputStream());
            if (CollectionUtils.isEmpty(userList)) {
                return AjaxResult.warn("模板错误或导入数据为空");
            }
            // æ ¹æ® type å‚数设置客户类型(私海/公海)
            if (type != null) {
                userList.forEach(customer -> {
                    customer.setType(type);
                });
            }
            this.saveOrUpdateBatch(userList);
            return AjaxResult.success(true);
@@ -245,6 +300,77 @@
        ).collect(Collectors.toList());
    }
    // åˆ†é…å…¬æµ·å®¢æˆ·ç»™ç§æµ·
    @Override
    public void assignCustomer(CustomerDto customerDto) {
        Customer customer = customerMapper.selectById(customerDto.getId());
        if (customer.getType() == 1 && customer.getIsAssigned() == 0) {  // å…¬æµ·ä¸”可分配
            customer.setIsAssigned(1);
            customer.setUsageStatus(1L);
            customer.setUsageUser(customerDto.getUsageUser());
            customerMapper.updateById(customer);
        }
    }
    // å›žæ”¶ç§æµ·å®¢æˆ·åˆ°å…¬æµ·
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void recycleCustomer(CustomerDto customerDto) {
        Customer customer = customerMapper.selectById(customerDto.getId());
        if (customer.getType() == 1 && customer.getIsAssigned() == 1) {  // å…¬æµ·ä¸”已分配
            customer.setIsAssigned(0);
            customer.setUsageStatus(0L);
            customer.setUsageUser(0L);
            customerMapper.updateById(customer);
            // åˆ é™¤è¯¥å®¢æˆ·çš„æ‰€æœ‰å…±äº«å…³ç³»
            customerUserService.remove(
                new QueryWrapper<CustomerUser>().lambda()
                    .eq(CustomerUser::getCustomerId, customerDto.getId())
            );
        }
    }
    // å®¢æˆ·å…±äº«
    @Override
    public void together(CustomerDto customerDto) {
        // æŸ¥è¯¢çŽ°æœ‰çš„å…±äº«è®°å½•
        List<CustomerUser> existingUsers = customerUserService.list(
                new QueryWrapper<CustomerUser>().lambda().eq(CustomerUser::getCustomerId, customerDto.getId())
        );
        // èŽ·å–å·²å­˜åœ¨çš„ç”¨æˆ·ID列表
        List<Long> existingUserIds = existingUsers.stream()
                .map(CustomerUser::getUserId)
                .collect(Collectors.toList());
        // è¿‡æ»¤æŽ‰å·²å­˜åœ¨çš„用户,只保留新用户
        List<Long> newUserIds = customerDto.getUserIds().stream()
                .filter(userId -> !existingUserIds.contains(userId))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(newUserIds)) {
            return;
        }
        // èŽ·å–å½“å‰ç§Ÿæˆ·ID
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long tenantId = loginUser.getTenantId();
        // æ‰¹é‡ä¿å­˜æ–°çš„共享记录
        List<CustomerUser> customerUsers = newUserIds.stream()
                .map(userId -> {
                    CustomerUser customerUser = new CustomerUser();
                    customerUser.setCustomerId(customerDto.getId());
                    customerUser.setUserId(userId);
                    customerUser.setTenantId(tenantId);
                    return customerUser;
                })
                .collect(Collectors.toList());
        customerUserService.saveBatch(customerUsers);
    }
    /**
     * ä¸‹åˆ’线命名转驼峰命名
     */
@@ -266,4 +392,4 @@
        }
        return sb.toString();
    }
}
}
src/main/java/com/ruoyi/basic/service/impl/CustomerUserServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package com.ruoyi.basic.service.impl;
import com.ruoyi.basic.mapper.CustomerUserMapper;
import com.ruoyi.basic.pojo.CustomerUser;
import com.ruoyi.basic.service.CustomerUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * å®¢æˆ·å…±äº«Service实现类
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @date 2026-04-29
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class CustomerUserServiceImpl extends ServiceImpl<CustomerUserMapper, CustomerUser> implements CustomerUserService {
}
src/main/java/com/ruoyi/basic/task/ReturnVisitReminderTask.java
@@ -76,7 +76,7 @@
        }
        try {
            unipushService.sendReturnVisitReminder(returnVisitId, client.getCid(), returnVisit.getContent(), returnVisit.getCustomerPrivatePoolId());
            unipushService.sendReturnVisitReminder(returnVisitId, client.getCid(), returnVisit.getContent(), returnVisit.getCustomerId());
            CustomerReturnVisit updateObj = new CustomerReturnVisit();
            updateObj.setId(returnVisitId);
            updateObj.setIsCompleted(1);
src/main/java/com/ruoyi/basic/vo/CustomerVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.ruoyi.basic.vo;
import com.ruoyi.basic.dto.CustomerFollowUpDto;
import com.ruoyi.basic.pojo.Customer;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
public class CustomerVo extends Customer {
    @ApiModelProperty(value = "跟进记录")
    private List<CustomerFollowUpDto> followUpList;
    private String usageUserName;
    private String togetherUserNames;
    /**
     * å…±äº«ç”¨æˆ·ID列表
     */
    private List<Long> userIds;
    /**
     * å…±äº«ç”¨æˆ·ID字符串(SQL查询返回,用于转换为List)
     */
    private String userIdsStr;
}
src/main/java/com/ruoyi/inspectiontask/service/impl/InspectionTaskServiceImpl.java
@@ -162,9 +162,18 @@
            dto.setDateStr(inspectionTask.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            // åˆå§‹åŒ–三个附件列表
            dto.setCommonFileList(finalCommonFiles.stream().filter(commonFile -> commonFile.getType().equals(FileNameType.INSPECTION.getValue())).collect(Collectors.toList()));
            dto.setCommonFileListAfter(finalCommonFiles.stream().filter(commonFile -> commonFile.getType().equals(FileNameType.INSPECTION_PRODUCTION_AFTER.getValue())).collect(Collectors.toList()));
            dto.setCommonFileListBefore(finalCommonFiles.stream().filter(commonFile -> commonFile.getType().equals(FileNameType.INSPECTION_PRODUCTION_BEFORE.getValue())).collect(Collectors.toList()));
            List<CommonFile> taskFiles = finalCommonFiles.stream()
                    .filter(commonFile -> Objects.equals(commonFile.getCommonId(), inspectionTask.getId()))
                    .collect(Collectors.toList());
            dto.setCommonFileList(taskFiles.stream()
                    .filter(commonFile -> Objects.equals(commonFile.getType(), FileNameType.INSPECTION.getValue()))
                    .collect(Collectors.toList()));
            dto.setCommonFileListAfter(taskFiles.stream()
                    .filter(commonFile -> Objects.equals(commonFile.getType(), FileNameType.INSPECTION_PRODUCTION_AFTER.getValue()))
                    .collect(Collectors.toList()));
            dto.setCommonFileListBefore(taskFiles.stream()
                    .filter(commonFile -> Objects.equals(commonFile.getType(), FileNameType.INSPECTION_PRODUCTION_BEFORE.getValue()))
                    .collect(Collectors.toList()));
            return dto;
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -4,7 +4,6 @@
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper;
import com.ruoyi.stock.dto.StockInRecordDto;
import com.ruoyi.stock.dto.StockInventoryDto;
import com.ruoyi.stock.dto.StockUninventoryDto;
import com.ruoyi.stock.mapper.StockInventoryMapper;
@@ -14,21 +13,15 @@
import com.ruoyi.stock.service.StockInventoryService;
import com.ruoyi.stock.service.StockOutRecordService;
import com.ruoyi.stock.service.StockUninventoryService;
import com.ruoyi.stock.service.impl.StockInRecordServiceImpl;
import com.ruoyi.stock.service.impl.StockOutRecordServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@Component
@RequiredArgsConstructor
public class StockUtils {
    private final ProcurementRecordOutMapper procurementRecordOutMapper;
    private final ProcurementRecordMapper procurementRecordMapper;
    private final StockUninventoryService stockUninventoryService;
    private final StockInventoryService stockInventoryService;
    private final StockInRecordService stockInRecordService;
src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java
@@ -140,7 +140,7 @@
    /**
     * å‘送回访提醒
     */
    public void sendReturnVisitReminder(Long returnVisitId, String cid, String content, Integer customerId) {
    public void sendReturnVisitReminder(Long returnVisitId, String cid, String content, Long customerId) {
        String targetPath = "pages/cooperativeOffice/customerManage/detail?customerId=" + customerId;
        sendRoutingPush(returnVisitId, cid, "客户回访提醒", content, targetPath, false);
    }
src/main/java/com/ruoyi/purchase/service/impl/PaymentRegistrationServiceImpl.java
@@ -131,7 +131,8 @@
            accountExpense.setSupplierName(purchaseLedger.getSupplierName());
            accountExpense.setExpenseMoney(paymentRegistration.getCurrentPaymentAmount());
            accountExpense.setExpenseDescribed("付款支出");
            accountExpense.setExpenseMethod("0");
            accountExpense.setExpenseMethod(paymentRegistration.getPaymentMethod());
            accountExpense.setBusinessId(paymentRegistration.getId());
            accountExpense.setBusinessType(1);
            accountExpense.setInputTime(new Date());
src/main/java/com/ruoyi/sales/dto/SalesLedgerProductDto.java
@@ -65,4 +65,6 @@
    @ApiModelProperty(value = "退货总数")
    private BigDecimal totalReturnNum;
    private String supplierNameOrContractNo;
}
src/main/java/com/ruoyi/sales/pojo/SalesQuotation.java
@@ -23,6 +23,9 @@
    @Excel(name = "客户名称")
    private String customer;
    @ApiModelProperty(value = "客户id")
    private Long customerId;
    @ApiModelProperty(value = "业务员")
    @Excel(name = "业务员")
    private String salesperson;
src/main/java/com/ruoyi/sales/service/impl/ReceiptPaymentServiceImpl.java
@@ -8,7 +8,6 @@
import com.ruoyi.account.service.AccountIncomeService;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.sales.dto.CustomerInteractionDto;
import com.ruoyi.sales.dto.InvoiceLedgerDto;
import com.ruoyi.sales.dto.ReceiptPaymentDto;
import com.ruoyi.sales.dto.ReceiptPaymentExeclDto;
@@ -16,7 +15,6 @@
import com.ruoyi.sales.mapper.ReceiptPaymentMapper;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.pojo.InvoiceLedger;
import com.ruoyi.sales.pojo.ReceiptPayment;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
@@ -32,7 +30,6 @@
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class ReceiptPaymentServiceImpl extends ServiceImpl<ReceiptPaymentMapper,ReceiptPayment> implements ReceiptPaymentService {
@@ -82,9 +79,9 @@
                accountIncome.setIncomeType("3");
                accountIncome.setCustomerName(salesLedger.getCustomerName());
                accountIncome.setIncomeMoney(receiptPayment.getReceiptPaymentAmount());
                accountIncome.setIncomeMethod("0");
                accountIncome.setIncomeMethod(receiptPayment.getReceiptPaymentType());
                accountIncome.setInputTime(new Date());
                accountIncome.setInputUser(salesLedger.getEntryPerson());
                accountIncome.setInputUser(SecurityUtils.getLoginUser().getNickName());
                accountIncome.setIncomeDescribed("回款收入");
                accountIncome.setBusinessId(Long.parseLong(receiptPayment.getId().toString()));
                accountIncome.setBusinessType(1);
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -9,13 +9,10 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.account.service.AccountIncomeService;
import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
import com.ruoyi.basic.mapper.CustomerMapper;
import com.ruoyi.basic.mapper.CustomerPrivatePoolMapper;
import com.ruoyi.basic.mapper.ProductMapper;
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.pojo.CustomerPrivatePool;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.enums.SaleEnum;
import com.ruoyi.common.exception.base.BaseException;
@@ -131,8 +128,6 @@
    ;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private CustomerPrivatePoolMapper customerPrivatePoolMapper;
    @Override
    public List<SalesLedger> selectSalesLedgerList(SalesLedgerDto salesLedgerDto) {
@@ -599,7 +594,7 @@
    public int addOrUpdateSalesLedger(SalesLedgerDto salesLedgerDto) {
        try {
            // 1. æ ¡éªŒå®¢æˆ·ä¿¡æ¯
            CustomerPrivatePoolDto customer = customerPrivatePoolMapper.selectInfo(salesLedgerDto.getCustomerId());
            Customer customer = customerMapper.selectById(salesLedgerDto.getCustomerId());
            if (customer == null) {
                throw new BaseException("客户不存在");
            }
src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java
@@ -7,16 +7,12 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.service.IApproveProcessService;
import com.ruoyi.approve.service.impl.ApproveProcessServiceImpl;
import com.ruoyi.approve.bean.vo.ApproveGetAndUpdateVo;
import com.ruoyi.approve.bean.vo.ApproveProcessVO;
import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
import com.ruoyi.basic.mapper.CustomerPrivatePoolMapper;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.sales.dto.SalesQuotationDto;
import com.ruoyi.sales.mapper.SalesQuotationMapper;
src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
@@ -6,8 +6,8 @@
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.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.EnumUtil;
import com.ruoyi.common.utils.OrderUtils;
@@ -15,7 +15,6 @@
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.service.ShippingInfoService;
import com.ruoyi.stock.dto.StockInventoryDto;
import com.ruoyi.stock.dto.StockOutRecordDto;
import com.ruoyi.stock.dto.StockUninventoryDto;
@@ -45,10 +44,10 @@
@Service
@AllArgsConstructor
public class StockOutRecordServiceImpl extends ServiceImpl<StockOutRecordMapper, StockOutRecord> implements StockOutRecordService {
    private StockOutRecordMapper stockOutRecordMapper;
    private StockInventoryMapper stockInventoryMapper;
    private StockUninventoryMapper stockUninventoryMapper;
    private final ShippingInfoService shippingInfoService;
    private final StockOutRecordMapper stockOutRecordMapper;
    private final StockInventoryMapper stockInventoryMapper;
    private final StockUninventoryMapper stockUninventoryMapper;
    private final ShippingInfoMapper shippingInfoMapper;
    @Override
    public IPage<StockOutRecordDto> listPage(Page page, StockOutRecordDto stockOutRecordDto) {
@@ -105,7 +104,7 @@
            if ("13".equals(stockOutRecord.getRecordType())){
                // æ­¤ä¸º é”€å”®-发货出库 æ²¡æœ‰å…³è”记录才能成功删除
                // æŸ¥è¯¢å¯¹åº”是否含有销售出货记录
                ShippingInfo byId = shippingInfoService.getById(stockOutRecord.getRecordId());
                ShippingInfo byId = shippingInfoMapper.selectById(stockOutRecord.getRecordId());
                Assert.isNull(byId, StrUtil.format("{}存在销售出货记录,无法删除!!!",stockOutRecord.getOutboundBatches()));
            }
src/main/resources/mapper/account/AccountIncomeMapper.xml
@@ -24,7 +24,26 @@
        <if test="accountIncome.incomeType != null and accountIncome.incomeType != '' ">
            AND income_type = #{accountIncome.incomeType}
        </if>
        <if test="accountIncome.incomeMethod != null and accountIncome.incomeMethod != '' ">
        <if test="accountIncome.incomeMethodLabel != null and accountIncome.incomeMethodLabel != ''">
            AND (
            (
            business_type = 1
            AND income_method in
            <foreach collection="accountIncome.receiptPaymentMethodList" item="method" open="(" separator="," close=")">
                #{method}
            </foreach>
            )
            OR
            (
            business_type is null
            AND income_method in
            <foreach collection="accountIncome.paymentMethodList" item="method" open="(" separator="," close=")">
                #{method}
            </foreach>
            )
            )
        </if>
        <if test="(accountIncome.incomeMethodLabel == null or accountIncome.incomeMethodLabel == '') and accountIncome.incomeMethod != null and accountIncome.incomeMethod != '' ">
            AND income_method = #{accountIncome.incomeMethod}
        </if>
    </select>
src/main/resources/mapper/basic/CustomerMapper.xml
@@ -6,17 +6,23 @@
    <resultMap id="BaseResultMap" type="com.ruoyi.basic.pojo.Customer">
        <id column="id" property="id" />
    </resultMap>
    <select id="listPage" resultType="com.ruoyi.basic.dto.CustomerDto">
    <select id="listPage" resultType="com.ruoyi.basic.vo.CustomerVo">
        select
        c.*,
        u.user_name usage_user_name,
        (
        select group_concat(u2.user_name separator ', ')
        from customer_private_pool cpp2
        left join sys_user u2 on cpp2.bound_id = u2.user_id
        where cpp2.customer_id = c.id and cpp2.delete_flag = 0
        and cpp2.bound_id != c.usage_user
        ) as together_user_names
        from customer_user cu
        left join sys_user u2 on cu.user_id = u2.user_id
        where cu.customer_id = c.id
        and cu.user_id != c.usage_user
        ) as together_user_names,
        (
        select group_concat(cu.user_id separator ',')
        from customer_user cu
        where cu.customer_id = c.id
        and cu.user_id != c.usage_user
        ) as user_ids_str
        from customer c
        left join sys_user u on c.usage_user = u.user_id
        <where>
@@ -26,8 +32,79 @@
            <if test="c.customerType != null and c.customerType != ''">
                and customer_type = #{c.customerType}
            </if>
            <!-- å…¬æµ·æŸ¥è¯¢ï¼štype = 1(公海客户)-->
            <if test="c.type != null and c.type == 1">
                and type = #{c.type}
            </if>
            <!-- ç§æµ·æŸ¥è¯¢ï¼štype = 0(私海客户)或者 type = 1(公海客户)且已被分配,并且是自己领用、自己创建或者共享给自己的客户 -->
            <if test="c.type != null and c.type == 0">
                and (
                    (type = #{c.type} or (type = 1 and is_assigned = 1))
                    and (
                        c.usage_user = #{loginUserId}
                        or c.create_user = #{loginUserId}
                        or exists (
                            select 1 from customer_user cu
                            where cu.customer_id = c.id
                            and cu.user_id = #{loginUserId}
                        )
                    )
                )
            </if>
        </where>
    </select>
</mapper>
    <select id="list" resultType="com.ruoyi.basic.vo.CustomerVo">
        select
        c.*,
        u.user_name usage_user_name,
        (
        select group_concat(u2.user_name separator ', ')
        from customer_user cu
        left join sys_user u2 on cu.user_id = u2.user_id
        where cu.customer_id = c.id
        and cu.user_id != c.usage_user
        ) as together_user_names,
        (
        select group_concat(cu.user_id separator ',')
        from customer_user cu
        where cu.customer_id = c.id
        and cu.user_id != c.usage_user
        ) as user_ids_str
        from customer c
        left join sys_user u on c.usage_user = u.user_id
        <where>
            <if test="c.ids != null and c.ids.length > 0">
                and c.id in
                <foreach collection="c.ids" item="id" open="(" separator="," close=")">
                    #{id}
                </foreach>
            </if>
            <if test="c.customerName != null and c.customerName != ''">
                and customer_name like concat('%', #{c.customerName}, '%')
            </if>
            <if test="c.customerType != null and c.customerType != ''">
                and customer_type = #{c.customerType}
            </if>
            <!-- å…¬æµ·æŸ¥è¯¢ï¼štype = 1(公海客户)-->
            <if test="c.type != null and c.type == 1">
                and type = #{c.type}
            </if>
            <!-- ç§æµ·æŸ¥è¯¢ï¼štype = 0(私海客户)或者 type = 1(公海客户)且已被分配,并且是自己领用、自己创建或者共享给自己的客户 -->
            <if test="c.type != null and c.type == 0">
                and (
                    (type = #{c.type} or (type = 1 and is_assigned = 1))
                    and (
                        c.usage_user = #{loginUserId}
                        or c.create_user = #{loginUserId}
                        or exists (
                            select 1 from customer_user cu
                            where cu.customer_id = c.id
                            and cu.user_id = #{loginUserId}
                        )
                    )
                )
            </if>
        </where>
    </select>
</mapper>
src/main/resources/mapper/basic/CustomerPrivateMapper.xml
ÎļþÒÑɾ³ý
src/main/resources/mapper/basic/CustomerPrivatePoolMapper.xml
ÎļþÒÑɾ³ý
src/main/resources/mapper/purchase/PaymentRegistrationMapper.xml
@@ -183,47 +183,65 @@
        </where>
        ORDER BY T1.payment_date,T1.create_time DESC
    </select>
    <select id="supplierNameListPage" resultType="com.ruoyi.purchase.dto.PaymentRegistrationDto">
        SELECT
        T1.supplier_id ,
        T1.supplier_id,
        T1.supplier_name,
        SUM(T1.contract_amount) AS invoiceAmount,
        IFNULL(SUM(T2.current_payment_amount), 0) AS paymentAmount,
        IFNULL(SUM(T1.contract_amount) - IFNULL(SUM(T2.current_payment_amount), 0), 0) AS payableAmount
        T1.invoiceAmount,
        IFNULL(T2.paymentAmount, 0) AS paymentAmount,
        (T1.invoiceAmount - IFNULL(T2.paymentAmount, 0)) AS payableAmount
        FROM (
        SELECT id,supplier_id, supplier_name, SUM(contract_amount) contract_amount
        SELECT
        supplier_id,
        supplier_name,
        SUM(contract_amount) AS invoiceAmount
        FROM purchase_ledger
        GROUP BY supplier_id, supplier_name,id
        ) T1
        LEFT JOIN (
        SELECT purchase_ledger_id, SUM(current_payment_amount) current_payment_amount
        FROM payment_registration
        GROUP BY purchase_ledger_id
        ) T2 ON T1.id = T2.purchase_ledger_id
        <where>
            <if test="req.supplierName != null and req.supplierName != '' ">
                T1.supplier_name LIKE CONCAT ('%',#{req.supplierName},'%')
                AND supplier_name LIKE CONCAT ('%',#{req.supplierName},'%')
            </if>
        </where>
        GROUP BY T1.supplier_id, T1.supplier_name
        GROUP BY supplier_id, supplier_name
        ) T1
        LEFT JOIN (
        SELECT
        supplier_id,
        SUM(current_payment_amount) AS paymentAmount
        FROM payment_registration
        GROUP BY supplier_id
        ) T2 ON T1.supplier_id = T2.supplier_id
    </select>
    <select id="supplierNameListPageDetails" resultType="com.ruoyi.purchase.dto.PaymentRegistrationDto">
         SELECT
    T1.purchase_contract_number,
    T1.contract_amount AS invoiceAmount,
    IFNULL(SUM(T2.current_payment_amount), 0) AS paymentAmount,
    IFNULL((T1.contract_amount - IFNULL(SUM(T2.current_payment_amount), 0)), 0) AS payableAmount,
    T2.payment_date
    FROM purchase_ledger T1
    INNER JOIN payment_registration T2 ON T1.id = T2.purchase_ledger_id
    <where>
        T1.supplier_id = #{req.supplierId}
        <if test="req.supplierName != null and req.supplierName != '' ">
            AND T1.supplier_name LIKE CONCAT ('%', #{req.supplierName}, '%')
        </if>
    </where>
    GROUP BY T1.id, T1.purchase_contract_number, T1.contract_amount, T2.payment_date
        SELECT
        T2.id,
        T1.purchase_contract_number,
        T1.contract_amount AS invoiceAmount,
        IFNULL(T2.current_payment_amount, 0) AS paymentAmount,
        IFNULL((
        T1.contract_amount - IFNULL((
        SELECT SUM(T3.current_payment_amount)
        FROM payment_registration T3
        WHERE T3.purchase_ledger_id = T1.id
        AND (
        T3.payment_date &lt; T2.payment_date
        OR (T3.payment_date = T2.payment_date AND T3.id &lt;= T2.id)
        )
        ), 0)
        ), 0) AS payableAmount,
        T2.payment_date
        FROM purchase_ledger T1
        INNER JOIN payment_registration T2 ON T1.id = T2.purchase_ledger_id
        <where>
            T1.supplier_id = #{req.supplierId}
            <if test="req.supplierName != null and req.supplierName != '' ">
                AND T1.supplier_name LIKE CONCAT ('%', #{req.supplierName}, '%')
            </if>
        </where>
        ORDER BY T2.payment_date ASC, T2.id ASC
    </select>
</mapper>
src/main/resources/mapper/sales/InvoiceLedgerMapper.xml
@@ -110,28 +110,33 @@
    </select>
    <select id="invoiceLedgerSalesAccount" resultType="com.ruoyi.sales.dto.InvoiceLedgerDto">
         SELECT
    T1.customer_id AS id,
    T1.customer_name,
    SUM(T1.contract_amount) AS invoice_total,
    IFNULL(SUM(T2.receipt_payment_amount), 0) AS receipt_payment_amount,
    IFNULL(SUM(T1.contract_amount) - IFNULL(SUM(T2.receipt_payment_amount), 0), 0) AS unReceipt_payment_amount
FROM (
    SELECT id,customer_id, customer_name, SUM(contract_amount) contract_amount
    FROM sales_ledger
    GROUP BY customer_id, customer_name
) T1
LEFT JOIN (
    SELECT sales_ledger_id, SUM(receipt_payment_amount) receipt_payment_amount
    FROM receipt_payment
    GROUP BY sales_ledger_id
) T2 ON T1.id  = T2.sales_ledger_id
<where>
    <if test="invoiceLedgerDto.searchText != null and invoiceLedgerDto.searchText != '' ">
        T1.customer_name LIKE CONCAT('%',#{invoiceLedgerDto.searchText},'%')
    </if>
</where>
GROUP BY T1.customer_id, T1.customer_name
        SELECT
        T1.customer_id AS id,
        T1.customer_name,
        T1.invoice_total,
        IFNULL(T2.receipt_payment_amount, 0) AS receipt_payment_amount,
        IFNULL(T1.invoice_total - IFNULL(T2.receipt_payment_amount, 0), 0) AS unReceipt_payment_amount
        FROM (
        SELECT
        customer_id,
        customer_name,
        SUM(contract_amount) AS invoice_total
        FROM sales_ledger
        GROUP BY customer_id, customer_name
        ) T1
        LEFT JOIN (
        SELECT
        T3.customer_id,
        SUM(T2.receipt_payment_amount) AS receipt_payment_amount
        FROM receipt_payment T2
        LEFT JOIN sales_ledger T3 ON T3.id = T2.sales_ledger_id
        GROUP BY T3.customer_id
        ) T2 ON T1.customer_id = T2.customer_id
        <where>
            <if test="invoiceLedgerDto.searchText != null and invoiceLedgerDto.searchText != '' ">
                T1.customer_name LIKE CONCAT('%',#{invoiceLedgerDto.searchText},'%')
            </if>
        </where>
    </select>
    <select id="invoiceLedgerProductInfo" resultType="com.ruoyi.sales.dto.InvoiceRegistrationProductDto">
src/main/resources/mapper/sales/ReceiptPaymentMapper.xml
@@ -435,10 +435,21 @@
    <select id="invoiceLedgerSalesAccount" resultType="com.ruoyi.sales.dto.InvoiceLedgerDto">
        SELECT
        T2.id,
        T1.sales_contract_no,
        T1.contract_amount AS invoice_total,
        IFNULL(SUM(T2.receipt_payment_amount), 0) AS receipt_payment_amount,
        IFNULL((T1.contract_amount - IFNULL(SUM(T2.receipt_payment_amount), 0)), 0) AS unReceipt_payment_amount,
        IFNULL(T2.receipt_payment_amount, 0) AS receipt_payment_amount,
        IFNULL((
        T1.contract_amount - IFNULL((
        SELECT SUM(T3.receipt_payment_amount)
        FROM receipt_payment T3
        WHERE T3.sales_ledger_id = T1.id
        AND (
        T3.receipt_payment_date &lt; T2.receipt_payment_date
        OR (T3.receipt_payment_date = T2.receipt_payment_date AND T3.id &lt;= T2.id)
        )
        ), 0)
        ), 0) AS unReceipt_payment_amount,
        T2.receipt_payment_date
        FROM sales_ledger T1
        INNER JOIN receipt_payment T2 ON T1.id = T2.sales_ledger_id
@@ -448,7 +459,7 @@
                AND T1.customer_name LIKE CONCAT ('%', #{invoiceLedgerDto.searchText}, '%')
            </if>
        </where>
        GROUP BY T1.id, T1.sales_contract_no, T1.contract_amount, T2.receipt_payment_date
        ORDER BY T2.receipt_payment_date ASC, T2.id ASC
    </select>
</mapper>
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -99,6 +99,10 @@
            <if test="req.status != null and req.status ">
                AND slp.pending_tickets_total &gt; 0
            </if>
            <if test="req.supplierNameOrContractNo != null and req.supplierNameOrContractNo != ''">
                AND (sl.supplier_name like concat('%',#{req.supplierNameOrContractNo},'%') or
                sl.purchase_contract_number like concat('%',#{req.supplierNameOrContractNo},'%'))
            </if>
        </where>
        order by slp.register_date desc
    </select>
src/main/resources/mapper/sales/SalesQuotationMapper.xml
@@ -9,6 +9,7 @@
        FROM sales_quotation t1
        LEFT JOIN approve_process t2 ON t1.quotation_no = t2.approve_reason and t2.approve_type = 6
        WHERE 1=1
          and t2.approve_deleted = 0
        <if test="salesQuotationDto.quotationNo != null and salesQuotationDto.quotationNo != '' ">
            AND t1.quotation_no LIKE CONCAT('%',#{salesQuotationDto.quotationNo},'%')
        </if>