已添加27个文件
已修改38个文件
1374 ■■■■■ 文件已修改
src/main/java/com/ruoyi/account/controller/SalesReceiptReturnController.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/controller/SalesRefundAmountOrderController.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/dto/SalesReceiptReturnDto.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/dto/SalesRefundAmountOrderDto.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/mapper/SalesReceiptReturnMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/mapper/SalesRefundAmountOrderMapper.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/pojo/AccountExpense.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/pojo/SalesReceiptReturn.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/pojo/SalesRefundAmountOrder.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/SalesReceiptReturnService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/SalesRefundAmountOrderService.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/impl/SalesReceiptReturnServiceImpl.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/impl/SalesRefundAmountOrderServiceImpl.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerFollowUpFileServiceImpl.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/config/MybatisHandler.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/BaseEnum.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/IsDeleteEnum.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/PlanStageEnum.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/ReturnSaleProductDto.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/mapper/ReturnSaleProductMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/ReturnSaleProductService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnManagementServiceImpl.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnSaleProductServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/controller/InfoController.java 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/dto/SaveInfoDto.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/dto/UpdateStateInfo.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/mapper/InfoMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/pojo/ContractInfo.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/pojo/Info.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/pojo/Plan.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/pojo/PlanNode.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/pojo/ShippingAddress.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/service/InfoService.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/service/impl/InfoServiceImpl.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/service/impl/handle/ContractInfoHandleService.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoHandleService.java 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/service/impl/handle/ShippingAddressHandleService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/vo/InfoVo.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/vo/ListInfoVo.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/vo/SavePlanNodeVo.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/vo/SavePlanVo.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/vo/SearchInfoVo.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/controller/PurchaseReturnOrderProductsController.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/controller/PurchaseReturnOrdersController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/dto/PurchaseReturnOrderDto.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/dto/PurchaseReturnOrderProductsDto.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/mapper/PurchaseReturnOrderProductsMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/pojo/PurchaseReturnOrderProducts.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/PurchaseReturnOrderProductsService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/PurchaseReturnOrdersService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/PurchaseReturnOrderProductsServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/PurchaseReturnOrdersServiceImpl.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/controller/StaffSalaryMainController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/dto/CalculateSalaryDto.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/StaffSalaryMainService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java 68 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/StaffSalaryMainServiceImpl.java 54 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-newTest.yml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/account/SalesReceiptReturnMapper.xml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/account/SalesRefundAmountOrderMapper.xml 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ReturnSaleProductMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/projectManagement/InfoMapper.xml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/purchase/PurchaseReturnOrderProductsMapper.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/controller/SalesReceiptReturnController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
package com.ruoyi.account.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.account.dto.SalesReceiptReturnDto;
import com.ruoyi.account.pojo.SalesReceiptReturn;
import com.ruoyi.account.service.SalesReceiptReturnService;
import com.ruoyi.account.service.impl.SalesReceiptReturnServiceImpl;
import com.ruoyi.framework.web.domain.R;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * æ”¶æ¬¾é€€è´§è¡¨ å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-09 03:34:18
 */
@RestController
@RequestMapping("/salesReceiptReturn")
public class SalesReceiptReturnController {
    @Autowired
    private  SalesReceiptReturnService salesReceiptReturnService;
    @GetMapping("/page")
    @ApiOperation("收款退货表-分页查询")
    public R<IPage<SalesReceiptReturnDto>> page(SalesReceiptReturnDto salesReceiptReturnDto) {
        return R.ok(salesReceiptReturnService.pageSalesReceiptReturnDto(salesReceiptReturnDto));
    }
}
src/main/java/com/ruoyi/account/controller/SalesRefundAmountOrderController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package com.ruoyi.account.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.account.dto.SalesRefundAmountOrderDto;
import com.ruoyi.account.pojo.SalesRefundAmountOrder;
import com.ruoyi.account.service.SalesRefundAmountOrderService;
import com.ruoyi.framework.web.domain.R;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
 * é”€å”®ç®¡ç†--退款单 å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-07 10:16:47
 */
@RestController
@RequestMapping("/salesRefundAmountOrder")
public class SalesRefundAmountOrderController {
    @Autowired
    private SalesRefundAmountOrderService salesRefundAmountOrderService;
    @GetMapping("/page")
    public R pageSalesRefundAmountOrderDto(Page<SalesRefundAmountOrderDto> page, SalesRefundAmountOrderDto salesRefundAmountOrder) {
        return R.ok(salesRefundAmountOrderService.pageSalesRefundAmountOrderDto(page, salesRefundAmountOrder));
    }
    @ApiOperation("处理")
    @PostMapping("/dispose")
    public R dispose( SalesRefundAmountOrderDto salesRefundAmountOrderId) {
        return R.ok(salesRefundAmountOrderService.dispose(salesRefundAmountOrderId));
    }
}
src/main/java/com/ruoyi/account/dto/SalesReceiptReturnDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
package com.ruoyi.account.dto;
import com.ruoyi.account.pojo.SalesReceiptReturn;
import lombok.Data;
@Data
public class SalesReceiptReturnDto extends SalesReceiptReturn {
}
src/main/java/com/ruoyi/account/dto/SalesRefundAmountOrderDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.ruoyi.account.dto;
import com.ruoyi.account.pojo.SalesRefundAmountOrder;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class SalesRefundAmountOrderDto extends SalesRefundAmountOrder {
    @ApiModelProperty("退货单号")
    private String returnManagementNo;
    @ApiModelProperty("客户名称")
    private String customerName;
    @ApiModelProperty("销售单号")
    private String salesContractNo;
    @ApiModelProperty("创建人名称")
    private String createUserName;
}
src/main/java/com/ruoyi/account/mapper/SalesReceiptReturnMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.account.mapper;
import com.ruoyi.account.pojo.SalesReceiptReturn;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * æ”¶æ¬¾é€€è´§è¡¨ Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-09 03:34:18
 */
@Mapper
public interface SalesReceiptReturnMapper extends BaseMapper<SalesReceiptReturn> {
}
src/main/java/com/ruoyi/account/mapper/SalesRefundAmountOrderMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.account.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.account.dto.SalesRefundAmountOrderDto;
import com.ruoyi.account.pojo.SalesRefundAmountOrder;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
 * <p>
 * é”€å”®ç®¡ç†--退款单 Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-07 10:16:47
 */
@Mapper
public interface SalesRefundAmountOrderMapper extends BaseMapper<SalesRefundAmountOrder> {
    IPage<SalesRefundAmountOrderDto> pageSalesRefundAmountOrderDto(Page<SalesRefundAmountOrderDto> page,@Param("ew") SalesRefundAmountOrderDto salesRefundAmountOrder);
}
src/main/java/com/ruoyi/account/pojo/AccountExpense.java
@@ -35,7 +35,7 @@
    private Long businessId;
    /**
     * ä¸šåŠ¡ç±»åž‹ 1-付款 2-还款
     * ä¸šåŠ¡ç±»åž‹ 1-付款 2-还款 3-薪资发放
     */
    private Integer businessType;
src/main/java/com/ruoyi/account/pojo/SalesReceiptReturn.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,71 @@
package com.ruoyi.account.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
 * <p>
 * æ”¶æ¬¾é€€è´§è¡¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-09 03:34:18
 */
@Getter
@Setter
@TableName("sales_receipt_return")
@ApiModel(value = "SalesReceiptReturn对象", description = "收款退货表")
public class SalesReceiptReturn implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty("主键 ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("退款单号")
    private String refundId;
    @ApiModelProperty("付款账号")
    private String paymentAccount;
    @ApiModelProperty("付款账号名称")
    private String paymentAccountName;
    @ApiModelProperty("付款方式")
    private Byte paymentMethod;
    @ApiModelProperty("实际付款金额")
    private BigDecimal actualAmount;
    @ApiModelProperty("手续费")
    private BigDecimal fee;
    @ApiModelProperty("交易号")
    private String transactionNo;
    @ApiModelProperty("优惠金额")
    private BigDecimal discountAmount;
    @ApiModelProperty("创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty("更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty("创建者")
    @TableField(fill = FieldFill.INSERT)
    private Long createUser;
}
src/main/java/com/ruoyi/account/pojo/SalesRefundAmountOrder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
package com.ruoyi.account.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
/**
 * <p>
 * é”€å”®ç®¡ç†--退款单
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-07 10:16:47
 */
@Getter
@Setter
@TableName("sales_refund_amount_order")
@ApiModel(value = "SalesRefundAmountOrder对象", description = "销售管理--退款单")
public class SalesRefundAmountOrder implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("退货单号id")
    private Long returnManagementId;
    @ApiModelProperty("状态")
    private Integer status;
    @ApiModelProperty("应退款金额")
    private BigDecimal refundAmount;
    @ApiModelProperty("已退款金额")
    private BigDecimal refundedAmount;
    @ApiModelProperty("未退款金额")
    private BigDecimal notRefundedAmount;
    @ApiModelProperty("创建时间")
    @TableField(fill = FieldFill.INSERT)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime createTime;
    @ApiModelProperty("更新时间")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty("创建人id")
    private Long createUserId;
    @ApiModelProperty("更新人id")
    private Long updateUserId;
}
src/main/java/com/ruoyi/account/service/SalesReceiptReturnService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.account.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.account.dto.SalesReceiptReturnDto;
import com.ruoyi.account.pojo.SalesReceiptReturn;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * æ”¶æ¬¾é€€è´§è¡¨ æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-09 03:34:18
 */
public interface SalesReceiptReturnService extends IService<SalesReceiptReturn> {
    IPage<SalesReceiptReturnDto> pageSalesReceiptReturnDto(SalesReceiptReturnDto salesReceiptReturnDto);
}
src/main/java/com/ruoyi/account/service/SalesRefundAmountOrderService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.ruoyi.account.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.account.dto.SalesRefundAmountOrderDto;
import com.ruoyi.account.pojo.SalesRefundAmountOrder;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * é”€å”®ç®¡ç†--退款单 æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-07 10:16:47
 */
public interface SalesRefundAmountOrderService extends IService<SalesRefundAmountOrder> {
    IPage<SalesRefundAmountOrderDto> pageSalesRefundAmountOrderDto(Page<SalesRefundAmountOrderDto> page, SalesRefundAmountOrderDto salesRefundAmountOrder);
    Boolean addSalesRefundAmountOrderDto(SalesRefundAmountOrderDto salesRefundAmountOrder);
    Boolean dispose(SalesRefundAmountOrderDto salesRefundAmountOrder);
}
src/main/java/com/ruoyi/account/service/impl/SalesReceiptReturnServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package com.ruoyi.account.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.account.dto.SalesReceiptReturnDto;
import com.ruoyi.account.pojo.SalesReceiptReturn;
import com.ruoyi.account.mapper.SalesReceiptReturnMapper;
import com.ruoyi.account.service.SalesReceiptReturnService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * æ”¶æ¬¾é€€è´§è¡¨ æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-09 03:34:18
 */
@Service
public class SalesReceiptReturnServiceImpl extends ServiceImpl<SalesReceiptReturnMapper, SalesReceiptReturn> implements SalesReceiptReturnService {
    @Override
    public IPage<SalesReceiptReturnDto> pageSalesReceiptReturnDto(SalesReceiptReturnDto salesReceiptReturnDto) {
        return null;
    }
}
src/main/java/com/ruoyi/account/service/impl/SalesRefundAmountOrderServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package com.ruoyi.account.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.account.dto.SalesRefundAmountOrderDto;
import com.ruoyi.account.pojo.SalesRefundAmountOrder;
import com.ruoyi.account.mapper.SalesRefundAmountOrderMapper;
import com.ruoyi.account.service.SalesRefundAmountOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * <p>
 * é”€å”®ç®¡ç†--退款单 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-07 10:16:47
 */
@Service
public class SalesRefundAmountOrderServiceImpl extends ServiceImpl<SalesRefundAmountOrderMapper, SalesRefundAmountOrder> implements SalesRefundAmountOrderService {
    @Autowired
    private SalesRefundAmountOrderMapper salesRefundAmountOrderMapper;
    @Override
    public IPage<SalesRefundAmountOrderDto> pageSalesRefundAmountOrderDto(Page<SalesRefundAmountOrderDto> page, SalesRefundAmountOrderDto salesRefundAmountOrder) {
        return salesRefundAmountOrderMapper.pageSalesRefundAmountOrderDto(page, salesRefundAmountOrder);
    }
    @Override
    public Boolean addSalesRefundAmountOrderDto(SalesRefundAmountOrderDto salesRefundAmountOrder) {
        return this.save(salesRefundAmountOrder);
    }
    @Override
    public Boolean dispose(SalesRefundAmountOrderDto salesRefundAmountOrder) {
        return null;
    }
}
src/main/java/com/ruoyi/basic/service/impl/CustomerFollowUpFileServiceImpl.java
@@ -11,6 +11,8 @@
import com.ruoyi.basic.service.CustomerFollowUpService;
import com.ruoyi.common.vo.SimpleFileVo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.util.*;
@@ -28,10 +30,11 @@
 * @since 2026/03/04 14:53
 */
@Service
@RequiredArgsConstructor
public class CustomerFollowUpFileServiceImpl extends ServiceImpl<CustomerFollowUpFileMapper, CustomerFollowUpFile> implements CustomerFollowUpFileService {
    private final CustomerFollowUpService customerFollowUpService;
    @Autowired
    @Lazy
    private CustomerFollowUpService customerFollowUpService;
    @Override
src/main/java/com/ruoyi/common/config/MybatisHandler.java
@@ -14,9 +14,11 @@
    public void insertFill(MetaObject metaObject) {
        Integer userId = null;
        Long tenantId = null;
        String userName = null;
        try {
            userId = SecurityUtils.getUserId().intValue();
            tenantId = SecurityUtils.getLoginUser().getTenantId();
            userName = SecurityUtils.getUsername();
        } catch (Exception ignored) {
        }
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
@@ -25,6 +27,9 @@
        this.strictInsertFill(metaObject, "updateUser", Integer.class, userId);
        this.strictInsertFill(metaObject, "createUser", Long.class, userId == null ? 0 : userId.longValue());
        this.strictInsertFill(metaObject, "updateUser", Long.class, userId == null ? 0 : userId.longValue());
        this.strictInsertFill(metaObject, "createUserName", String.class, userName);
        this.strictInsertFill(metaObject, "updateUserName", String.class, userName);
        this.strictInsertFill(metaObject, "tenantId", Long.class, tenantId);
    }
src/main/java/com/ruoyi/common/enums/BaseEnum.java
@@ -1,6 +1,7 @@
package com.ruoyi.common.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
src/main/java/com/ruoyi/common/enums/IsDeleteEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.common.enums;
import lombok.Getter;
/**
 * @author buhuazhen
 * @date 2026/3/10
 * @email 3038525872@qq.com
 */
@Getter
public enum IsDeleteEnum implements BaseEnum<Integer> {
    NOT_DELETED(0, "未删除"),
    DELETED(1, "已删除");
    private final Integer code;
    private final String value;
    IsDeleteEnum(Integer code, String value) {
        this.code = code;
        this.value = value;
    }
}
src/main/java/com/ruoyi/common/enums/PlanStageEnum.java
@@ -1,5 +1,6 @@
package com.ruoyi.common.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonCreator;
import lombok.Getter;
@@ -15,12 +16,18 @@
    TO_BEGIN(1, "待开始"),
    ON_GOING(2, "进行中"),
    ENDED(3, "已结束");
    @EnumValue
    private final Integer code;
    private final String value;
    PlanStageEnum(Integer code, String value) {
        this.code = code;
        this.value = value;
    }
    @JsonCreator
    public static PlanStageEnum fromCode(Integer code) {
        return BaseEnum.fromCode(PlanStageEnum.class, code);
    }
}
src/main/java/com/ruoyi/procurementrecord/dto/ReturnSaleProductDto.java
@@ -18,4 +18,10 @@
    private BigDecimal unQuantity;
    private BigDecimal totalReturnNum;
    // é€€è´§æ€»ä»·
    private BigDecimal price;
    // é€€è´§æ€»ä»·
    private BigDecimal taxInclusiveUnitPrice;
}
src/main/java/com/ruoyi/procurementrecord/mapper/ReturnSaleProductMapper.java
@@ -20,4 +20,6 @@
public interface ReturnSaleProductMapper extends BaseMapper<ReturnSaleProduct> {
    List<ReturnSaleProductDto> listReturnSaleProductDto(@Param("returnManagementId") Long returnManagementId);
    List<ReturnSaleProductDto> listReturnSaleProduct(@Param("returnManagementId") Long returnManagementId);
}
src/main/java/com/ruoyi/procurementrecord/service/ReturnSaleProductService.java
@@ -17,4 +17,6 @@
public interface ReturnSaleProductService extends IService<ReturnSaleProduct> {
    List<ReturnSaleProductDto> listReturnSaleProductDto(Long returnManagementId);
    List<ReturnSaleProductDto> listReturnSaleProduct(Long returnManagementId);
}
src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnManagementServiceImpl.java
@@ -1,10 +1,16 @@
package com.ruoyi.procurementrecord.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.SalesRefundAmountOrderDto;
import com.ruoyi.account.pojo.SalesRefundAmountOrder;
import com.ruoyi.account.service.SalesRefundAmountOrderService;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.procurementrecord.dto.ReturnManagementDto;
import com.ruoyi.procurementrecord.dto.ReturnSaleProductDto;
import com.ruoyi.procurementrecord.mapper.ReturnManagementMapper;
import com.ruoyi.procurementrecord.pojo.ReturnManagement;
import com.ruoyi.procurementrecord.pojo.ReturnSaleProduct;
@@ -22,6 +28,7 @@
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@@ -42,6 +49,8 @@
    private ShippingInfoService shippingInfoService;
    @Autowired
    private SalesLedgerMapper salesLedgerMapper;
    @Autowired
    private SalesRefundAmountOrderService salesRefundAmountOrderService;
    @Override
    public IPage<ReturnManagementDto> listPage(Page page, ReturnManagementDto returnManagement) {
@@ -91,8 +100,22 @@
    @Override
    public boolean handle(Long returnManagementId) {
        ReturnManagement byId = this.getById(returnManagementId);
        List<ReturnSaleProductDto> list = returnSaleProductService.listReturnSaleProduct(returnManagementId);
        byId.setStatus(1);
        updateById(byId);
        SalesRefundAmountOrderDto salesRefundAmountOrder = new SalesRefundAmountOrderDto();
        salesRefundAmountOrder.setReturnManagementId(returnManagementId);
        salesRefundAmountOrder.setStatus(0);
        salesRefundAmountOrder.setCreateTime(byId.getCreateTime());
        salesRefundAmountOrder.setCreateUserId(SecurityUtils.getUserId());
        BigDecimal bigDecimal = new BigDecimal(0);
        for (ReturnSaleProductDto returnSaleProduct : list) {
            bigDecimal = bigDecimal.add(returnSaleProduct.getPrice());
            salesRefundAmountOrder.setRefundedAmount(new BigDecimal(0));
        }
        salesRefundAmountOrder.setRefundAmount(bigDecimal);
        salesRefundAmountOrder.setNotRefundedAmount(salesRefundAmountOrder.getRefundedAmount());
        salesRefundAmountOrderService.addSalesRefundAmountOrderDto(salesRefundAmountOrder);
        return true;
    }
src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnSaleProductServiceImpl.java
@@ -29,4 +29,9 @@
        return returnSaleProductMapper.listReturnSaleProductDto(returnManagementId);
    }
    @Override
    public List<ReturnSaleProductDto> listReturnSaleProduct(Long returnManagementId) {
        return returnSaleProductMapper.listReturnSaleProduct(returnManagementId);
    }
}
src/main/java/com/ruoyi/projectManagement/controller/InfoController.java
@@ -1,14 +1,14 @@
package com.ruoyi.projectManagement.controller;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.projectManagement.dto.UpdateStateInfo;
import com.ruoyi.projectManagement.service.InfoService;
import com.ruoyi.projectManagement.vo.SaveInfoVo;
import com.ruoyi.projectManagement.vo.SearchInfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@@ -26,8 +26,38 @@
    private final InfoService infoService;
    @PostMapping("/save")
    @ApiOperation("保存")
    public AjaxResult save(@RequestBody @Valid SaveInfoVo saveInfoVo) {
        infoService.save(saveInfoVo);
        return AjaxResult.success();
    }
    @PostMapping("/updateStatus")
    @ApiOperation("修改状态")
    public AjaxResult updateStatus(@RequestBody @Valid UpdateStateInfo updateStateInfo){
        infoService.updateStatus(updateStateInfo);
        return AjaxResult.success();
    }
    @PostMapping("/delete/{id}")
    @ApiOperation("删除")
    public AjaxResult delete(@PathVariable Long id) {
        infoService.deleteInfo(id);
        return AjaxResult.success();
    }
    @PostMapping("/listPage")
    @ApiOperation("分页列表")
    public AjaxResult listPage(@RequestBody @Valid SearchInfoVo vo) {
        return AjaxResult.success(infoService.searchListInfo(vo));
    }
    @PostMapping("/{id}")
    @ApiOperation("详情")
    public AjaxResult getInfoById(@PathVariable Long id) {
        return AjaxResult.success(infoService.getInfoById(id));
    }
}
src/main/java/com/ruoyi/projectManagement/dto/SaveInfoDto.java
@@ -1,6 +1,8 @@
package com.ruoyi.projectManagement.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ruoyi.common.vo.SimpleFileVo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -24,7 +26,7 @@
public class SaveInfoDto implements Serializable {
    private Long id;
    private String no;
    @NotBlank
    @NotBlank(message = "title为空")
    private String title;
    private Long clientId;
    private String clientName;
@@ -35,7 +37,7 @@
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate establishTime;
    // é¡¹ç›®ç±»åž‹ id
    @NotNull
    @NotNull(message = "projectManagementPlanId为空")
    private Long projectManagementPlanId;
    private String source;
@@ -43,7 +45,7 @@
    private Long managerId;
    private String managerName;
    private Long salesmanId;
        private String salesmanName;
    private String salesmanName;
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
@@ -61,6 +63,9 @@
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate actualEndTime;
    // å®¡æ ¸çŠ¶æ€
    private Integer reviewStatus;
    // é¡¹ç›®çŠ¶æ€
    private Integer status;
@@ -76,7 +81,14 @@
    private String remark;
    @JsonIgnore
    private String attachment;
    private List<SimpleFileVo> attachmentList;
    private List<String> attachmentIds; // é™„ä»¶ids
    private List<TeamDto> teamList;
    private List<PlanStageDto> planStage;
}
src/main/java/com/ruoyi/projectManagement/dto/UpdateStateInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.ruoyi.projectManagement.dto;
import com.ruoyi.common.enums.PlanStageEnum;
import com.ruoyi.common.enums.ReviewStatusEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
 * @author buhuazhen
 * @date 2026/3/10
 * @email 3038525872@qq.com
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UpdateStateInfo implements Serializable {
    @NotNull(message = "id不能为空")
    private Long id;
    // å®¡æ‰¹çŠ¶æ€
    private ReviewStatusEnum reviewStatus;
    // è¿›åº¦çŠ¶æ€
    private PlanStageEnum stage;
}
src/main/java/com/ruoyi/projectManagement/mapper/InfoMapper.java
@@ -1,7 +1,11 @@
package com.ruoyi.projectManagement.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.projectManagement.pojo.Info;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.projectManagement.vo.ListInfoVo;
import com.ruoyi.projectManagement.vo.SearchInfoVo;
import org.apache.ibatis.annotations.Param;
/**
* @author buhuazhen
@@ -11,6 +15,7 @@
*/
public interface InfoMapper extends BaseMapper<Info> {
    Page<ListInfoVo> searchListInfo(@Param("vo") SearchInfoVo vo);
}
src/main/java/com/ruoyi/projectManagement/pojo/ContractInfo.java
@@ -127,6 +127,12 @@
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @TableField(value = "create_user_name", fill = FieldFill.INSERT)
    private String createUserName;
    @TableField(value = "update_user_name", fill = FieldFill.INSERT_UPDATE)
    private String updateUserName;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
src/main/java/com/ruoyi/projectManagement/pojo/Info.java
@@ -207,4 +207,10 @@
    @TableField(value = "team",typeHandler = JacksonTypeHandler.class)
    private List<TeamDto> team;
    @TableField(value = "create_user_name", fill = FieldFill.INSERT)
    private String createUserName;
    @TableField(value = "update_user_name", fill = FieldFill.INSERT_UPDATE)
    private String updateUserName;
}
src/main/java/com/ruoyi/projectManagement/pojo/Plan.java
@@ -81,4 +81,10 @@
    @TableField(value = "update_user",fill = FieldFill.INSERT_UPDATE)
    @ApiModelProperty(value="更新人")
    private Integer updateUser;
    @TableField(value = "create_user_name", fill = FieldFill.INSERT)
    private String createUserName;
    @TableField(value = "update_user_name", fill = FieldFill.INSERT_UPDATE)
    private String updateUserName;
}
src/main/java/com/ruoyi/projectManagement/pojo/PlanNode.java
@@ -99,6 +99,12 @@
    @TableField(value = "update_user",fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @TableField(value = "create_user_name", fill = FieldFill.INSERT)
    private String createUserName;
    @TableField(value = "update_user_name", fill = FieldFill.INSERT_UPDATE)
    private String updateUserName;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
src/main/java/com/ruoyi/projectManagement/pojo/ShippingAddress.java
@@ -70,6 +70,13 @@
    @TableField(value = "project_management_info_id")
    private Long projectManagementInfoId;
    @TableField(value = "create_user_name", fill = FieldFill.INSERT)
    private String createUserName;
    @TableField(value = "update_user_name", fill = FieldFill.INSERT_UPDATE)
    private String updateUserName;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
src/main/java/com/ruoyi/projectManagement/service/InfoService.java
@@ -1,6 +1,11 @@
package com.ruoyi.projectManagement.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.projectManagement.dto.UpdateStateInfo;
import com.ruoyi.projectManagement.vo.InfoVo;
import com.ruoyi.projectManagement.vo.ListInfoVo;
import com.ruoyi.projectManagement.vo.SaveInfoVo;
import com.ruoyi.projectManagement.vo.SearchInfoVo;
import javax.validation.constraints.NotNull;
@@ -10,6 +15,35 @@
 * @email 3038525872@qq.com
 */
public interface InfoService {
    /**
     * ä¿å­˜é¡¹ç›®ä¿¡æ¯
     *
     * @param saveInfoVo ä¿å­˜é¡¹ç›®ä¿¡æ¯çš„DTO
     */
    void save(@NotNull SaveInfoVo saveInfoVo);
    /**
     * æ›´æ–°é¡¹ç›®ä¿¡æ¯çŠ¶æ€
     *
     * @param updateStateInfo æ›´æ–°é¡¹ç›®ä¿¡æ¯çŠ¶æ€çš„DTO
     */
    void updateStatus(@NotNull UpdateStateInfo updateStateInfo);
    /**
     * åˆ é™¤é¡¹ç›®ä¿¡æ¯
     *
     * @param id é¡¹ç›®ä¿¡æ¯ID
     */
    void deleteInfo(@NotNull Long id);
    /**
     * åˆ†é¡µæŸ¥è¯¢é¡¹ç›®ä¿¡æ¯åˆ—表
     *
     * @param vo æŸ¥è¯¢æ¡ä»¶
     * @return é¡¹ç›®ä¿¡æ¯åˆ—表
     */
    Page<ListInfoVo> searchListInfo(@NotNull SearchInfoVo vo);
    InfoVo getInfoById(@NotNull Long id);
}
src/main/java/com/ruoyi/projectManagement/service/impl/InfoServiceImpl.java
@@ -1,15 +1,33 @@
package com.ruoyi.projectManagement.service.impl;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.enums.IsDeleteEnum;
import com.ruoyi.common.enums.SaleEnum;
import com.ruoyi.projectManagement.dto.ContractInfoDto;
import com.ruoyi.projectManagement.dto.SaveInfoDto;
import com.ruoyi.projectManagement.dto.ShippingAddressDto;
import com.ruoyi.projectManagement.dto.UpdateStateInfo;
import com.ruoyi.projectManagement.mapper.InfoMapper;
import com.ruoyi.projectManagement.pojo.Info;
import com.ruoyi.projectManagement.service.InfoService;
import com.ruoyi.projectManagement.service.impl.handle.ContractInfoHandleService;
import com.ruoyi.projectManagement.service.impl.handle.InfoHandleService;
import com.ruoyi.projectManagement.service.impl.handle.ShippingAddressHandleService;
import com.ruoyi.projectManagement.vo.InfoVo;
import com.ruoyi.projectManagement.vo.ListInfoVo;
import com.ruoyi.projectManagement.vo.SaveInfoVo;
import com.ruoyi.projectManagement.vo.SearchInfoVo;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.service.ISalesLedgerService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
 * @author buhuazhen
@@ -21,17 +39,93 @@
@Transactional(readOnly = true)
public class InfoServiceImpl implements InfoService {
    private final InfoHandleService infoHandleService;
    private final InfoMapper infoMapper;
    private final ContractInfoHandleService contractInfoHandleService;
    private final ShippingAddressHandleService shippingAddressHandleService;
    private final ISalesLedgerService salesLedgerService;
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(SaveInfoVo saveInfoVo) {
        // ä¿å­˜ä¸»ä¿¡æ¯
        Long infoId = infoHandleService.save(saveInfoVo.getInfo());
        shippingAddressHandleService.save(infoId, saveInfoVo.getShippingAddress());
        contractInfoHandleService.save(infoId, saveInfoVo.getContractInfo());
        salesLedgerService.handleSalesLedgerProducts(infoId, saveInfoVo.getSalesLedgerProductList(), SaleEnum.MANAGEMENT);
        if(saveInfoVo.getShippingAddress() != null){
            shippingAddressHandleService.save(infoId, saveInfoVo.getShippingAddress());
        }
        if(saveInfoVo.getContractInfo() != null){
            contractInfoHandleService.save(infoId, saveInfoVo.getContractInfo());
        }
        if(saveInfoVo.getSalesLedgerProductList() != null){
            salesLedgerService.handleSalesLedgerProducts(infoId, saveInfoVo.getSalesLedgerProductList(), SaleEnum.MANAGEMENT);
        }
    }
    @Override
    @Transactional
    public void updateStatus(UpdateStateInfo updateStateInfo) {
        Info info = new Info();
        info.setId(updateStateInfo.getId());
        // å®¡æ‰¹çŠ¶æ€
        if(updateStateInfo.getReviewStatus() != null){
            info.setReviewStatus(updateStateInfo.getReviewStatus().getCode());
        }
        // è¿›åº¦çŠ¶æ€
        if(updateStateInfo.getStage() != null){
            info.setStatus(updateStateInfo.getStage().getCode());
        }
        infoMapper.updateById(info);
    }
    @Override
    @Transactional
    public void deleteInfo(Long id) {
        LambdaUpdateWrapper<Info> updateWrapper = new LambdaUpdateWrapper<Info>();
        updateWrapper.eq(Info::getId, id);
        updateWrapper.set(Info::getIsDelete, IsDeleteEnum.DELETED.getCode());
        // å¯¹åº”附表信息是否删除待确定(因为后续可能会进行引用所以先不删除
    }
    @Override
    public Page<ListInfoVo> searchListInfo(SearchInfoVo vo) {
        Page<ListInfoVo> listInfoVoPage = infoMapper.searchListInfo(vo);
        return listInfoVoPage;
    }
    @Override
    @SneakyThrows
    public InfoVo getInfoById(Long id) {
        CompletableFuture<SaveInfoDto> infoFuture = CompletableFuture.supplyAsync(() -> infoHandleService.getInfoById(id));
        CompletableFuture<ContractInfoDto> contractFuture = CompletableFuture.supplyAsync(() -> contractInfoHandleService.getByInfoId(id));
        CompletableFuture<ShippingAddressDto> shippingFuture = CompletableFuture.supplyAsync(() -> shippingAddressHandleService.getByInfoId(id));
        // å•†å“
        CompletableFuture<List<SalesLedgerProduct>> listCompletableFuture = CompletableFuture.supplyAsync(() -> salesLedgerService.getSalesLedgerProductListByRelateId(id,SaleEnum.MANAGEMENT));
        // ä¸‹çº§é¡¹ç›®ä¿¡æ¯
        CompletableFuture<List<SaveInfoDto>> subordinateInfoListFuture = CompletableFuture.supplyAsync(() -> infoHandleService.getSubordinateInfo(id));
        // ç­‰å¾…所有异步完成
        CompletableFuture.allOf(infoFuture, contractFuture, shippingFuture,listCompletableFuture,subordinateInfoListFuture).join();
        SaveInfoDto info = infoFuture.get();
        ContractInfoDto contract = contractFuture.get();
        ShippingAddressDto shippingAddress = shippingFuture.get();
        List<SalesLedgerProduct> salesLedgerProductList = listCompletableFuture.get();
        List<SaveInfoDto> saveInfoDtos = subordinateInfoListFuture.get();
        InfoVo vo = new InfoVo();
        vo.setInfo(info);
        vo.setContractInfo(contract);
        vo.setShippingAddress(shippingAddress);
        vo.setSalesLedgerProductList(salesLedgerProductList);
        vo.setSubordinateInfoList(saveInfoDtos);
        return vo;
    }
}
src/main/java/com/ruoyi/projectManagement/service/impl/handle/ContractInfoHandleService.java
@@ -1,10 +1,12 @@
package com.ruoyi.projectManagement.service.impl.handle;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.projectManagement.dto.ContractInfoDto;
import com.ruoyi.projectManagement.mapper.ContractInfoMapper;
import com.ruoyi.projectManagement.pojo.ContractInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -17,11 +19,11 @@
 * @email 3038525872@qq.com
 */
@Component
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class,readOnly = true)
public class ContractInfoHandleService{
    private final ContractInfoMapper contractInfoMapper;
    @Autowired
    private ContractInfoMapper contractInfoMapper;
    @Transactional(rollbackFor = Exception.class)
    public void save(@Nullable Long id, @NotNull ContractInfoDto contractInfoDto) {
@@ -33,4 +35,14 @@
            contractInfoMapper.updateById(contractInfo);
        }
    }
    public ContractInfoDto getByInfoId(@NotNull Long id) {
        LambdaQueryWrapper<ContractInfo> queryWrapper = new LambdaQueryWrapper<ContractInfo>();
        queryWrapper.eq(ContractInfo::getProjectManagementInfoId, id);
        queryWrapper.eq(ContractInfo::getIsDelete, 0);
        queryWrapper.last("limit 1");
        ContractInfo contractInfo = contractInfoMapper.selectOne(queryWrapper);
        return BeanUtil.copyProperties(contractInfo, ContractInfoDto.class);
    }
}
src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoHandleService.java
@@ -4,16 +4,16 @@
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.ruoyi.basic.service.CustomerFollowUpFileService;
import com.ruoyi.common.enums.PlanStageEnum;
import com.ruoyi.common.enums.ReviewStatusEnum;
import com.ruoyi.common.utils.EnumUtil;
import com.ruoyi.projectManagement.dto.PlanStageDto;
import com.ruoyi.projectManagement.dto.SaveInfoDto;
import com.ruoyi.projectManagement.mapper.InfoMapper;
import com.ruoyi.projectManagement.pojo.Info;
import com.ruoyi.projectManagement.pojo.PlanNode;
import com.ruoyi.projectManagement.service.PlanService;
import com.ruoyi.projectManagement.service.impl.PlanServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -31,7 +31,7 @@
 */
@Component
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class,readOnly = true)
@Transactional(rollbackFor = Exception.class, readOnly = true)
public class InfoHandleService {
    private static final String GENERATE_SERIAL_NUMBER_PREFIX = "XM";
@@ -40,8 +40,10 @@
    private final PlanService planService;
    private final CustomerFollowUpFileService customerFollowUpFileService;
    @Transactional(rollbackFor = Exception.class)
    public Long save(@NotNull SaveInfoDto saveInfoDto){
    public Long save(@NotNull SaveInfoDto saveInfoDto) {
        Info info = BeanUtil.copyProperties(saveInfoDto, Info.class);
        // é™„件特殊处理
@@ -49,32 +51,61 @@
        info.setAttachment(attachmentIds);
        // ç”Ÿæˆåºå· (如果需要自动生成的话)
        if(StrUtil.isBlank(info.getNo())){
        if (StrUtil.isBlank(info.getNo())) {
            info.setNo(generateSerialNumber());
        }
        info.setTeam(saveInfoDto.getTeamList());
        if(info.getId() == null){
        if (info.getId() == null) {
            // ç”Ÿæˆå¯¹åº”的阶段关系数据
            info.setPlanStage(getPlanStageList(info.getProjectManagementPlanId()));
            // æ’入默认状态
            info.setStatus(PlanStageEnum.TO_BEGIN.getCode());
            info.setReviewStatus(ReviewStatusEnum.PENDING_REVIEW.getCode());
            infoMapper.insert(info);
        }else {
        } else {
            infoMapper.updateById(info);
        }
        return info.getId();
    }
    public SaveInfoDto getInfoById(@NotNull Long id) {
        Info info = infoMapper.selectById(id);
        return convert(info);
    }
    private SaveInfoDto convert(Info info) {
        SaveInfoDto saveInfoDto = BeanUtil.copyProperties(info, SaveInfoDto.class);
        // é™„件处理
        saveInfoDto.setTeamList(info.getTeam());
        customerFollowUpFileService.fillAttachment(Lists.newArrayList(saveInfoDto), SaveInfoDto::getAttachment, SaveInfoDto::setAttachmentList);
        return saveInfoDto;
    }
    /**
     * èŽ·å–æ”¹id下子项目信息
     *
     * @param id
     * @return
     */
    public List<SaveInfoDto> getSubordinateInfo(@NotNull Long id) {
        LambdaQueryWrapper<Info> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Info::getProjectManagementInfoParentId, id);
        queryWrapper.orderByAsc(Info::getCreateTime);
        List<Info> infoList = infoMapper.selectList(queryWrapper);
        return infoList.stream().map(this::convert).collect(Collectors.toList());
    }
    private List<PlanStageDto> getPlanStageList(@NotNull Long planId) {
        List<PlanNode> planNodeByPlanId = planService.getPlanNodeByPlanId(planId);
        return planNodeByPlanId.stream().map(it-> new PlanStageDto(it.getId(), it.getName(), PlanStageEnum.TO_BEGIN)).collect(Collectors.toList());
        return planNodeByPlanId.stream().map(it -> new PlanStageDto(it.getId(), it.getName(), PlanStageEnum.TO_BEGIN)).collect(Collectors.toList());
    }
    /**
     * ç”Ÿæˆé¡¹ç›®ç¼–号
     *
     * @return
     */
    private String generateSerialNumber() {
src/main/java/com/ruoyi/projectManagement/service/impl/handle/ShippingAddressHandleService.java
@@ -1,6 +1,7 @@
package com.ruoyi.projectManagement.service.impl.handle;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.projectManagement.dto.ShippingAddressDto;
import com.ruoyi.projectManagement.mapper.ShippingAddressMapper;
import com.ruoyi.projectManagement.pojo.ShippingAddress;
@@ -33,4 +34,14 @@
            shippingAddressMapper.updateById(shippingAddress);
        }
    }
    public ShippingAddressDto getByInfoId(@NotNull Long id) {
        LambdaQueryWrapper<ShippingAddress> queryWrapper = new LambdaQueryWrapper<ShippingAddress>();
        queryWrapper.eq(ShippingAddress::getProjectManagementInfoId, id);
        queryWrapper.eq(ShippingAddress::getIsDelete, 0);
        queryWrapper.last("limit 1");
        ShippingAddress shippingAddress = shippingAddressMapper.selectOne(queryWrapper);
        return BeanUtil.copyProperties(shippingAddress, ShippingAddressDto.class);
    }
}
src/main/java/com/ruoyi/projectManagement/vo/InfoVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.ruoyi.projectManagement.vo;
import com.ruoyi.projectManagement.dto.SaveInfoDto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
 * @author buhuazhen
 * @date 2026/3/10
 * @email 3038525872@qq.com
 */
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class InfoVo extends SaveInfoVo implements Serializable {
    // é¡¹ç›®é˜¶æ®µ
    private String xxx;
    // ä¸‹çº§é¡¹ç›®
    private List<SaveInfoDto> subordinateInfoList;
}
src/main/java/com/ruoyi/projectManagement/vo/ListInfoVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package com.ruoyi.projectManagement.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.projectManagement.dto.SaveInfoDto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
 * é¡µé¢åˆ—表信息
 *
 * @author buhuazhen
 * @date 2026/3/10
 * @email 3038525872@qq.com
 */
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ListInfoVo extends SaveInfoDto implements Serializable {
    // å¯¹åº”项目类型名称
    private String projectManagementPlanName;
    // å¯¹åº”父项目名称
    private String projectManagementInfoParentName;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime; // åˆ›å»ºæ—¶é—´
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime; // æ›´æ–°æ—¶é—´
    private String createUserName; // åˆ›å»ºäººåç§°
    private String updateUserName; // æ›´æ–°äººåç§°
}
src/main/java/com/ruoyi/projectManagement/vo/SavePlanNodeVo.java
@@ -23,13 +23,13 @@
    private Integer sort;
    @NotBlank
    @NotBlank(message = "name不能为空")
    private String name;
    @NotNull
    @NotNull(message = "leaderId不能为空")
    private Long leaderId;
    @NotBlank
    @NotBlank(message = "leaderName不能为空")
    private String leaderName;
    private Integer estimatedDuration;
src/main/java/com/ruoyi/projectManagement/vo/SavePlanVo.java
@@ -22,7 +22,7 @@
public class SavePlanVo implements Serializable {
    private Long id;
    @NotBlank
    @NotBlank(message = "name不能为空")
    private String name;
//    @NotBlank
    private String description;
src/main/java/com/ruoyi/projectManagement/vo/SearchInfoVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.ruoyi.projectManagement.vo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.enums.PlanStageEnum;
import com.ruoyi.common.enums.ReviewStatusEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
 * @author buhuazhen
 * @date 2026/3/10
 * @email 3038525872@qq.com
 */
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SearchInfoVo extends Page implements Serializable {
    private String noOrName; // é¡¹ç›®ç¼–号或项目名称
    private String clientName; // å®¢æˆ·åç§°
    private String salesmanName; // ä¸šåŠ¡å‘˜
    // å®¡æ‰¹çŠ¶æ€
    private ReviewStatusEnum reviewStatus;
    // è¿›åº¦çŠ¶æ€
    private PlanStageEnum stage;
}
src/main/java/com/ruoyi/purchase/controller/PurchaseReturnOrderProductsController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.purchase.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 *  å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-09 01:37:44
 */
@RestController
@RequestMapping("/purchaseReturnOrderProducts")
public class PurchaseReturnOrderProductsController {
}
src/main/java/com/ruoyi/purchase/controller/PurchaseReturnOrdersController.java
@@ -42,6 +42,6 @@
        if (purchaseReturnOrderDto.getIsDefaultNo()) {
            purchaseReturnOrderDto.setNo(OrderUtils.countTodayByCreateTime(purchaseReturnOrdersMapper, "CGTL"));
        }
        return AjaxResult.success(purchaseReturnOrdersService.save(purchaseReturnOrderDto));
        return AjaxResult.success(purchaseReturnOrdersService.add(purchaseReturnOrderDto));
    }
}
src/main/java/com/ruoyi/purchase/dto/PurchaseReturnOrderDto.java
@@ -1,10 +1,16 @@
package com.ruoyi.purchase.dto;
import com.ruoyi.purchase.pojo.PurchaseReturnOrderProducts;
import com.ruoyi.purchase.pojo.PurchaseReturnOrders;
import lombok.Data;
import java.util.List;
@Data
public class PurchaseReturnOrderDto extends PurchaseReturnOrders {
    // æ˜¯å¦ä½¿ç”¨ç³»ç»Ÿå•号
    private Boolean isDefaultNo;
    private List<PurchaseReturnOrderProductsDto> purchaseReturnOrderProductsDtos;
}
src/main/java/com/ruoyi/purchase/dto/PurchaseReturnOrderProductsDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.ruoyi.purchase.dto;
import com.ruoyi.purchase.pojo.PurchaseReturnOrderProducts;
import lombok.Data;
@Data
public class PurchaseReturnOrderProductsDto extends PurchaseReturnOrderProducts {
    private String productName;
    private String model;
    private String unit;
}
src/main/java/com/ruoyi/purchase/mapper/PurchaseReturnOrderProductsMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.purchase.mapper;
import com.ruoyi.purchase.pojo.PurchaseReturnOrderProducts;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 *  Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-09 01:37:44
 */
@Mapper
public interface PurchaseReturnOrderProductsMapper extends BaseMapper<PurchaseReturnOrderProducts> {
}
src/main/java/com/ruoyi/purchase/pojo/PurchaseReturnOrderProducts.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package com.ruoyi.purchase.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
 * <p>
 *
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-09 01:37:44
 */
@Getter
@Setter
@TableName("purchase_return_order_products")
@ApiModel(value = "PurchaseReturnOrderProducts对象", description = "")
public class PurchaseReturnOrderProducts implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("退货单id")
    private Long purchaseReturnOrderId;
    @ApiModelProperty("采购产品id")
    private Long salesLedgerProductId;
    @ApiModelProperty("录入时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty("更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty("退货数量")
    private BigDecimal num;
}
src/main/java/com/ruoyi/purchase/service/PurchaseReturnOrderProductsService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.purchase.service;
import com.ruoyi.purchase.pojo.PurchaseReturnOrderProducts;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 *  æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-09 01:37:44
 */
public interface PurchaseReturnOrderProductsService extends IService<PurchaseReturnOrderProducts> {
}
src/main/java/com/ruoyi/purchase/service/PurchaseReturnOrdersService.java
@@ -17,4 +17,6 @@
 */
public interface PurchaseReturnOrdersService extends IService<PurchaseReturnOrders> {
    IPage<PurchaseReturnOrderVo> listPage(Page page, PurchaseReturnOrderDto purchaseReturnOrderDto);
    Boolean add(PurchaseReturnOrderDto purchaseReturnOrderDto);
}
src/main/java/com/ruoyi/purchase/service/impl/PurchaseReturnOrderProductsServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.purchase.service.impl;
import com.ruoyi.purchase.pojo.PurchaseReturnOrderProducts;
import com.ruoyi.purchase.mapper.PurchaseReturnOrderProductsMapper;
import com.ruoyi.purchase.service.PurchaseReturnOrderProductsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 *  æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-09 01:37:44
 */
@Service
public class PurchaseReturnOrderProductsServiceImpl extends ServiceImpl<PurchaseReturnOrderProductsMapper, PurchaseReturnOrderProducts> implements PurchaseReturnOrderProductsService {
}
src/main/java/com/ruoyi/purchase/service/impl/PurchaseReturnOrdersServiceImpl.java
@@ -3,6 +3,8 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.purchase.dto.PurchaseReturnOrderDto;
import com.ruoyi.purchase.dto.PurchaseReturnOrderProductsDto;
import com.ruoyi.purchase.mapper.PurchaseReturnOrderProductsMapper;
import com.ruoyi.purchase.pojo.PurchaseReturnOrders;
import com.ruoyi.purchase.mapper.PurchaseReturnOrdersMapper;
import com.ruoyi.purchase.service.PurchaseReturnOrdersService;
@@ -10,6 +12,7 @@
import com.ruoyi.purchase.vo.PurchaseReturnOrderVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * <p>
@@ -23,9 +26,24 @@
public class PurchaseReturnOrdersServiceImpl extends ServiceImpl<PurchaseReturnOrdersMapper, PurchaseReturnOrders> implements PurchaseReturnOrdersService {
    @Autowired
    private PurchaseReturnOrdersMapper purchaseReturnOrdersMapper;
    @Autowired
    private PurchaseReturnOrderProductsMapper purchaseReturnOrderProductsMapper;
    @Override
    public IPage<PurchaseReturnOrderVo> listPage(Page page, PurchaseReturnOrderDto purchaseReturnOrderDto) {
        return purchaseReturnOrdersMapper.listPage(page, purchaseReturnOrderDto);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(PurchaseReturnOrderDto purchaseReturnOrderDto) {
        this.save(purchaseReturnOrderDto);
        if (purchaseReturnOrderDto.getPurchaseReturnOrderProductsDtos().isEmpty()) {
            for (PurchaseReturnOrderProductsDto purchaseReturnOrderProductsDto :purchaseReturnOrderDto.getPurchaseReturnOrderProductsDtos()) {
                purchaseReturnOrderProductsDto.setPurchaseReturnOrderId(purchaseReturnOrderDto.getId());
                purchaseReturnOrderProductsMapper.insert(purchaseReturnOrderProductsDto);
            }
        }
        return true;
    }
}
src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
@@ -13,6 +13,7 @@
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
@@ -30,6 +31,8 @@
    int addOrUpdateSalesLedger(SalesLedgerDto salesLedgerDto);
    List<SalesLedgerProduct> getSalesLedgerProductListByRelateId(@NotNull Long relateId,@NotNull SaleEnum type);
    void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products, SaleEnum type);
    SalesLedgerDto getSalesLedgerWithProducts(SalesLedgerDto salesLedgerDto);
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -160,6 +160,14 @@
        return salesLedgerMapper.selectSalesLedgerList(salesLedgerDto);
    }
    public List<SalesLedgerProduct> getSalesLedgerProductListByRelateId(Long relateId, SaleEnum type){
        LambdaQueryWrapper<SalesLedgerProduct> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(SalesLedgerProduct::getSalesLedgerId, relateId);
        productWrapper.eq(SalesLedgerProduct::getType, type.getCode());
        return salesLedgerProductMapper.selectList(productWrapper);
    }
    @Override
    public SalesLedgerDto getSalesLedgerWithProducts(SalesLedgerDto salesLedgerDto) {
        // 1. æŸ¥è¯¢ä¸»è¡¨
src/main/java/com/ruoyi/staff/controller/StaffSalaryMainController.java
@@ -4,6 +4,7 @@
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.staff.dto.CalculateSalaryDto;
import com.ruoyi.staff.pojo.StaffSalaryMain;
import com.ruoyi.staff.service.StaffSalaryMainService;
import io.swagger.annotations.Api;
@@ -39,8 +40,8 @@
    @ApiOperation("通过部门ids获取用户信息计算每个员工的工资")
    @PostMapping("/calculateSalary")
    public AjaxResult calculateSalary(@RequestBody List<Long> ids) {
        return staffSalaryMainService.calculateSalary(ids);
    public AjaxResult calculateSalary(@RequestBody CalculateSalaryDto calculateSalaryDto) {
        return staffSalaryMainService.calculateSalary(calculateSalaryDto);
    }
    @PostMapping("/add")
src/main/java/com/ruoyi/staff/dto/CalculateSalaryDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.staff.dto;
import lombok.Data;
import java.util.List;
/**
 * @author :yys
 * @date : 2026/3/9 11:53
 */
@Data
public class CalculateSalaryDto {
    private List<Long> ids;
    private String date;
}
src/main/java/com/ruoyi/staff/service/StaffSalaryMainService.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.staff.dto.CalculateSalaryDto;
import com.ruoyi.staff.pojo.StaffSalaryMain;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -25,5 +26,5 @@
    AjaxResult delete(List<Long> ids);
    AjaxResult calculateSalary(List<Long> ids);
    AjaxResult calculateSalary(CalculateSalaryDto calculateSalaryDto);
}
src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java
@@ -4,6 +4,9 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.production.dto.UserAccountDto;
import com.ruoyi.production.dto.UserProductionAccountingDto;
import com.ruoyi.production.service.SalesLedgerProductionAccountingService;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.domain.SysUserDept;
@@ -58,6 +61,9 @@
    @Autowired
    private StaffOnJobMapper staffOnJobMapper;
    @Autowired
    private SalesLedgerProductionAccountingService salesLedgerProductionAccountingService;
    @Override
@@ -160,20 +166,20 @@
     * é€šè¿‡å‘˜å·¥id计算社保方案
     * @param id
     */
    public void calculateByEmployeeId(Integer id,Map<String, Object> map) {
    public void calculateByEmployeeId(Integer id,Map<String, Object> map,String date) {
        // 1. å…¥å‚校验
        if (id == null) {
            return; // æˆ–返回空列表,根据业务需求调整
        }
        Long staffId = id.longValue();
        // ç¤¾ä¿é‡‘额
        BigDecimal schemeAmount = new BigDecimal("0.00");
        BigDecimal socialPersonal = new BigDecimal("0.00");
        // å…¬ç§¯é‡‘金额
        BigDecimal gjj = new BigDecimal("0.00");
        BigDecimal fundPersonal = new BigDecimal("0.00");
        // åŸºæœ¬å·¥èµ„
        BigDecimal basicSalary = new BigDecimal("0.00");
        map.put("gjj", gjj); // å…¬ç§¯é‡‘
        map.put("schemeAmount", schemeAmount); // ç¤¾ä¿é‡‘额
        map.put("fundPersonal", fundPersonal); // å…¬ç§¯é‡‘
        map.put("socialPersonal", socialPersonal); // ç¤¾ä¿é‡‘额
        map.put("basicSalary", basicSalary); // åŸºæœ¬å·¥èµ„
        // ä¸ªç¨Žé‡‘额
        BigDecimal salaryTax = new BigDecimal("0.00");
@@ -209,8 +215,22 @@
        // åº”发工资
        map.put("grossSalary", basicSalary);
        // ä¸ªç¨Žé‡‘额(无社保版)
        BigDecimal bigDecimal = TaxCalculator.calculateMonthlyTax(basicSalary, schemeAmount, gjj);
        BigDecimal bigDecimal = TaxCalculator.calculateMonthlyTax(basicSalary, socialPersonal, fundPersonal);
        map.put("salaryTax", bigDecimal);
        // è®¡æ—¶å·¥èµ„ è®¡ä»¶å·¥èµ„
        UserProductionAccountingDto userProductionAccountingDto = new UserProductionAccountingDto();
        userProductionAccountingDto.setUserId(getUidByStaffId(staffId));
        userProductionAccountingDto.setDate(date);
        UserAccountDto byUserId = salesLedgerProductionAccountingService.getByUserId(userProductionAccountingDto);
        if(byUserId != null){
            map.put("pieceSalary", byUserId.getAccountBalance());
            map.put("hourlySalary", byUserId.getAccount());
            // åº”发 å®žå‘增加
            grossSalary = grossSalary.add(byUserId.getAccountBalance()).add(byUserId.getAccount());
            map.put("grossSalary", grossSalary);
            netSalary = netSalary.add(byUserId.getAccountBalance()).add(byUserId.getAccount());
            map.put("netSalary", netSalary);
        }
        // 2. æŸ¥è¯¢è¯¥äººå‘˜å¯¹åº”的社保方案
        List<SchemeApplicableStaff> schemeList = schemeApplicableStaffMapper.selectSchemeByStaffId(staffId);
        if (CollectionUtils.isEmpty(schemeList)) {
@@ -224,26 +244,46 @@
                continue;
            }
            for (SchemeInsuranceDetail detail : detailList) {
                if("住房公积金".equals(detail.getInsuranceType())){
                    gjj = gjj.add(calculateByEmployeeIdType(detail.getInsuranceType(),gjj, staffOnJobDto, detail));
                if("公积金".equals(detail.getInsuranceType())){
                    fundPersonal = fundPersonal.add(calculateByEmployeeIdType(detail.getInsuranceType(),fundPersonal, staffOnJobDto, detail));
                }else{
                    schemeAmount = schemeAmount.add(calculateByEmployeeIdType(detail.getInsuranceType(),schemeAmount, staffOnJobDto, detail));
                    socialPersonal = socialPersonal.add(calculateByEmployeeIdType(detail.getInsuranceType(),socialPersonal, staffOnJobDto, detail));
                }
            }
        }
        map.put("schemeAmount", schemeAmount);
        map.put("gjj", gjj);
        map.put("socialPersonal", socialPersonal);
        map.put("fundPersonal", fundPersonal);
        // ä¸ªç¨Žé‡‘额(社保版)
        bigDecimal = TaxCalculator.calculateMonthlyTax(basicSalary, schemeAmount, gjj);
        bigDecimal = TaxCalculator.calculateMonthlyTax(basicSalary, socialPersonal, fundPersonal);
        map.put("salaryTax", bigDecimal);
        // åº”扣工资
        map.put("deductSalary", bigDecimal.add(gjj).add(schemeAmount));
        map.put("deductSalary", bigDecimal.add(fundPersonal).add(socialPersonal));
        // å®žå‘工资
        map.put("netSalary", basicSalary.subtract(bigDecimal).subtract(gjj).subtract(schemeAmount));
        map.put("netSalary", basicSalary.subtract(bigDecimal).subtract(fundPersonal).subtract(socialPersonal));
    }
    /**
     * é€šè¿‡å‘˜å·¥Id获取用户id
     * @param staffId
     * @return
     */
    public Long getUidByStaffId(Long staffId){
        StaffOnJob staffOnJob = staffOnJobMapper.selectById(staffId);
        if(staffOnJob == null){
            return -1L; // è¿”回不存在Id
        }
        SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserName, staffOnJob.getStaffNo())
                .eq(SysUser::getDelFlag, "0")
                .last("limit 1"));
        if(sysUser == null){
            return -1L; // è¿”回不存在Id
        }
        return sysUser.getUserId();
    }
    /**
     * è®¡ç®—
     * @param type
     * @param bigDecimal
src/main/java/com/ruoyi/staff/service/impl/StaffSalaryMainServiceImpl.java
@@ -2,14 +2,20 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.account.mapper.AccountExpenseMapper;
import com.ruoyi.account.pojo.AccountExpense;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.domain.SysUserDept;
import com.ruoyi.project.system.mapper.SysUserDeptMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.staff.dto.CalculateSalaryDto;
import com.ruoyi.staff.mapper.StaffOnJobMapper;
import com.ruoyi.staff.mapper.StaffSalaryDetailMapper;
import com.ruoyi.staff.pojo.SchemeApplicableStaff;
import com.ruoyi.staff.pojo.StaffOnJob;
import com.ruoyi.staff.pojo.StaffSalaryDetail;
import com.ruoyi.staff.pojo.StaffSalaryMain;
import com.ruoyi.staff.mapper.StaffSalaryMainMapper;
@@ -53,6 +59,12 @@
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private StaffOnJobMapper staffOnJobMapper;
    @Autowired
    private AccountExpenseMapper accountExpenseMapper;
    @Override
    public AjaxResult listPage(Page page, StaffSalaryMain staffSalaryMain) {
        LambdaQueryWrapper<StaffSalaryMain> staffSalaryMainLambdaQueryWrapper = new LambdaQueryWrapper<>();
@@ -95,15 +107,32 @@
            return AjaxResult.error("参数错误");
        }
        // å¾…审核不可编辑
        if(staffSalaryMain1.getStatus() > 2){
            return AjaxResult.error("待审核不可编辑");
        }
//        if(staffSalaryMain1.getStatus() > 3){
//            return AjaxResult.error("待审核不可编辑");
//        }
        staffSalaryMainMapper.updateById(staffSalaryMain);
        staffSalaryDetailMapper.delete(new LambdaQueryWrapper<StaffSalaryDetail>().eq(StaffSalaryDetail::getMainId, staffSalaryMain.getId()));
        staffSalaryMain.getStaffSalaryDetailList().forEach(detail -> {
            detail.setMainId(staffSalaryMain.getId());
        });
        staffSalaryDetailService.saveBatch(staffSalaryMain.getStaffSalaryDetailList());
        if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(staffSalaryMain.getStaffSalaryDetailList())){
            staffSalaryDetailMapper.delete(new LambdaQueryWrapper<StaffSalaryDetail>().eq(StaffSalaryDetail::getMainId, staffSalaryMain.getId()));
            staffSalaryMain.getStaffSalaryDetailList().forEach(detail -> {
                detail.setMainId(staffSalaryMain.getId());
            });
            staffSalaryDetailService.saveBatch(staffSalaryMain.getStaffSalaryDetailList());
        }
        // å’Œè´¢åŠ¡è”åŠ¨ï¼Œæ–°å¢žæ”¯å‡º
        if(staffSalaryMain.getStatus().equals(5)){
            AccountExpense accountExpense = new AccountExpense();
            accountExpense.setBusinessType(3);
            accountExpense.setExpenseMoney(staffSalaryMain.getTotalSalary());
            accountExpense.setBusinessId(staffSalaryMain.getId());
            accountExpense.setExpenseDate(new Date());
            accountExpense.setExpenseMethod("2");
            accountExpense.setExpenseType("1");
            accountExpense.setExpenseDescribed(staffSalaryMain.getSalaryTitle());
            accountExpense.setNote(staffSalaryMain.getRemark());
            accountExpense.setInputUser(SecurityUtils.getLoginUser().getNickName());
            accountExpense.setInputTime(new Date());
            accountExpenseMapper.insert(accountExpense);
        }
        return AjaxResult.success("修改成功");
    }
@@ -118,16 +147,16 @@
    }
    @Override
    public AjaxResult calculateSalary(List<Long> ids) {
        if(CollectionUtils.isEmpty(ids)){
    public AjaxResult calculateSalary(CalculateSalaryDto calculateSalaryDto) {
        if(CollectionUtils.isEmpty(calculateSalaryDto.getIds())){
            return AjaxResult.error("参数错误");
        }
        List<Map<String, Object>> longs = setSchemeApplicableStaffUserInfo(ids); // é€šè¿‡éƒ¨é—¨ids获取用户信息
        List<Map<String, Object>> longs = setSchemeApplicableStaffUserInfo(calculateSalaryDto.getIds()); // é€šè¿‡éƒ¨é—¨ids获取用户信息
        if(CollectionUtils.isEmpty(longs)){
            return AjaxResult.error("无员工");
        }
        for (Map<String, Object> id : longs) {
            schemeApplicableStaffService.calculateByEmployeeId((Integer) id.get("id"),id);
            schemeApplicableStaffService.calculateByEmployeeId((Integer) id.get("id"),id,calculateSalaryDto.getDate());
        }
        return AjaxResult.success(longs);
    }
@@ -139,4 +168,5 @@
        // é€šè¿‡éƒ¨é—¨èŽ·å–äººå‘˜id
        return sysUserDeptMapper.setSchemeApplicableStaffUserInfo(ids);
    }
}
src/main/resources/application-newTest.yml
@@ -15,6 +15,14 @@
  captchaType: math
  # ååŒå®¡æ‰¹ç¼–号前缀(配置文件后缀命名)
  approvalNumberPrefix: NEWTEST
  # ä¸ªæŽ¨ Unipush é…ç½®
  getui:
    appId: PfjyAAE0FK64FaO1w2CMb1
    appKey: zTMb831OEL6J4GK1uE3Ob4
    masterSecret: K1GFtsv42v61tXGnF7SGE5
    domain: https://restapi.getui.cn/v2/
    # ç¦»çº¿æŽ¨é€ä½¿ç”¨çš„包名/组件名
    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
src/main/resources/mapper/account/SalesReceiptReturnMapper.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.account.mapper.SalesReceiptReturnMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.account.pojo.SalesReceiptReturn">
        <id column="id" property="id" />
        <result column="refund_id" property="refundId" />
        <result column="payment_account" property="paymentAccount" />
        <result column="payment_account_name" property="paymentAccountName" />
        <result column="payment_method" property="paymentMethod" />
        <result column="actual_amount" property="actualAmount" />
        <result column="fee" property="fee" />
        <result column="transaction_no" property="transactionNo" />
        <result column="discount_amount" property="discountAmount" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
        <result column="create_user" property="createUser" />
    </resultMap>
</mapper>
src/main/resources/mapper/account/SalesRefundAmountOrderMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
<?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.account.mapper.SalesRefundAmountOrderMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.account.pojo.SalesRefundAmountOrder">
        <id column="id" property="id" />
        <result column="return_management_id" property="returnManagementId" />
        <result column="status" property="status" />
        <result column="refund_amount" property="refundAmount" />
        <result column="refunded_amount" property="refundedAmount" />
        <result column="not_refunded_amount" property="notRefundedAmount" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
        <result column="create_user_id" property="createUserId" />
        <result column="update_user_id" property="updateUserId" />
    </resultMap>
    <select id="pageSalesRefundAmountOrderDto" resultType="com.ruoyi.account.dto.SalesRefundAmountOrderDto">
        select sl.sales_contract_no,
        sl.customer_contract_no,
        slp.specification_model,
        slp.product_category as product_name,
        slp.unit,
        sl.customer_name,
        rm.return_no as return_management_no,
        srao.*
        from sales_refund_amount_order srao
        left join return_management rm on srao.return_management_id = rm.id
        left join return_sale_product rs on rm.id = rs.return_management_id
        left join sales_ledger_product slp on rs.return_sale_ledger_product_id = slp.id
        left join sales_ledger sl on slp.sales_ledger_id = sl.id
        <where>
            <if test="ew.salesContractNo != null and ew.salesContractNo !=''">
                and sl.sales_contract_no like concat('%',#{ew.salesContractNo},'%')
            </if>
            <if test="ew.returnManagementNo != null and ew.returnManagementNo !=''">
                and rm.return_no like concat('%',#{ew.returnManagementNo},'%')
            </if>
        </where>
    </select>
</mapper>
src/main/resources/mapper/procurementrecord/ReturnSaleProductMapper.xml
@@ -28,5 +28,11 @@
                            GROUP BY return_sale_ledger_product_id) rs ON rs.return_sale_ledger_product_id = slp.id
        where rm.id =#{returnManagementId}
    </select>
    <select id="listReturnSaleProduct" resultType="com.ruoyi.procurementrecord.dto.ReturnSaleProductDto">
        select rsp.*,slp.tax_inclusive_unit_price ,slp.tax_inclusive_total_price*rsp.num as price
        from return_sale_product rsp
                 left join sales_ledger_product slp on slp.id = rsp.return_sale_ledger_product_id
        where rsp.return_management_id = #{returnManagementId}
    </select>
</mapper>
src/main/resources/mapper/projectManagement/InfoMapper.xml
@@ -48,4 +48,27 @@
        department_name,order_date,order_amount,
        remark,attachment
    </sql>
    <select id="searchListInfo" resultType="com.ruoyi.projectManagement.vo.ListInfoVo">
        select t1.*, t2.name as project_management_plan_name,t3.title as projectManagementInfoParentName
        from project_management_info as t1
        left join project_management_plan as t2 on t1.project_management_plan_id = t2.id
        left join project_management_info as t3 on t1.project_management_info_parent_id = t3.id
        where t1.is_delete = 0
        <if test="vo.noOrName != null and vo.noOrName != ''">
            and ( t1.no like concat('%', #{vo.noOrName}, '%') OR t1.title like concat('%', #{vo.noOrName}, '%') )
        </if>
        <if test="vo.clientName != null and vo.clientName != ''">
            and t1.client_name like concat('%', #{vo.clientName}, '%')
        </if>
        <if test="vo.salesmanName != null and vo.salesmanName != ''">
            and t1.salesman_name like concat('%', #{vo.salesmanName}, '%')
        </if>
        <if test="vo.reviewStatus != null">
            and t1.review_status = #{vo.reviewStatus.code}
        </if>
        <if test="vo.stage != null">
            and t1.stage = #{vo.stage.code}
        </if>
        order by t1.create_time desc
    </select>
</mapper>
src/main/resources/mapper/purchase/PurchaseReturnOrderProductsMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
<?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.purchase.mapper.PurchaseReturnOrderProductsMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.purchase.pojo.PurchaseReturnOrderProducts">
        <id column="id" property="id" />
        <result column="purchase_return_order_id" property="purchaseReturnOrderId" />
        <result column="sales_ledger_product_id" property="salesLedgerProductId" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
        <result column="num" property="num" />
    </resultMap>
</mapper>