挂账需求
This commit is contained in:
parent
e3833b8bfc
commit
3f03cd2583
|
|
@ -0,0 +1,97 @@
|
|||
package com.czg.controller.admin;
|
||||
|
||||
import com.czg.log.annotation.OperationLog;
|
||||
import com.czg.order.dto.CreditBuyerDTO;
|
||||
import com.czg.order.param.CreditBuyerQueryParam;
|
||||
import com.czg.order.param.CreditBuyerRepaymentParam;
|
||||
import com.czg.order.service.CreditBuyerService;
|
||||
import com.czg.order.vo.CreditBuyerRepaymentVo;
|
||||
import com.czg.resp.CzgResult;
|
||||
import com.czg.utils.AssertUtil;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
||||
/**
|
||||
* 挂账人
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/admin/order/credit/buyer")
|
||||
public class CreditBuyerController {
|
||||
private final CreditBuyerService creditBuyerService;
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*/
|
||||
@GetMapping("page")
|
||||
@OperationLog("挂账人-分页")
|
||||
//@SaAdminCheckPermission("creditBuyer:page")
|
||||
public CzgResult<Page<CreditBuyerDTO>> getCreditBuyerPage(CreditBuyerQueryParam param) {
|
||||
Page<CreditBuyerDTO> data = creditBuyerService.getCreditBuyerPage(param);
|
||||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
* param id 挂账人id
|
||||
*/
|
||||
@GetMapping("{id}")
|
||||
@OperationLog("挂账人-详情")
|
||||
//@SaAdminCheckPermission("creditBuyer:info")
|
||||
public CzgResult<CreditBuyerDTO> getCreditBuyerById(@PathVariable("id") String id) {
|
||||
AssertUtil.isNull(id, "{}不能为空", "id");
|
||||
CreditBuyerDTO data = creditBuyerService.getCreditBuyerById(id);
|
||||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
@PostMapping
|
||||
@OperationLog("挂账人-新增")
|
||||
//@SaAdminCheckPermission("creditBuyer:add")
|
||||
public CzgResult<Void> addCreditBuyer(@RequestBody CreditBuyerDTO dto) {
|
||||
creditBuyerService.addCreditBuyer(dto);
|
||||
return CzgResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@PutMapping
|
||||
@OperationLog("挂账人-修改")
|
||||
//@SaAdminCheckPermission("creditBuyer:update")
|
||||
public CzgResult<Void> updateCreditBuyer(@RequestBody CreditBuyerDTO dto) {
|
||||
creditBuyerService.updateCreditBuyer(dto);
|
||||
return CzgResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param id 挂账人id
|
||||
*/
|
||||
@DeleteMapping("{id}")
|
||||
@OperationLog("挂账人-删除")
|
||||
//@SaAdminCheckPermission("creditBuyer:delete")
|
||||
public CzgResult<Void> deleteCreditBuyer(@PathVariable("id") String id) {
|
||||
//效验数据
|
||||
AssertUtil.isNull(id, "{}不能为空", "id");
|
||||
creditBuyerService.deleteCreditBuyer(id);
|
||||
return CzgResult.success();
|
||||
}
|
||||
|
||||
@PostMapping("repayment")
|
||||
@OperationLog("挂账人-还款")
|
||||
//@SaAdminCheckPermission("creditBuyer:repayment")
|
||||
public CzgResult<CreditBuyerRepaymentVo> repayment(@RequestBody CreditBuyerRepaymentParam param) {
|
||||
CreditBuyerRepaymentVo data = creditBuyerService.repayment(param);
|
||||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package com.czg.controller.admin;
|
||||
|
||||
import com.czg.log.annotation.OperationLog;
|
||||
import com.czg.order.dto.CreditBuyerOrderDTO;
|
||||
import com.czg.order.entity.CreditPaymentRecord;
|
||||
import com.czg.order.param.CreditBuyerOrderQueryParam;
|
||||
import com.czg.order.service.CreditBuyerOrderService;
|
||||
import com.czg.order.vo.CreditBuyerOrderSummaryVo;
|
||||
import com.czg.resp.CzgResult;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
||||
/**
|
||||
* 挂账账单
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/admin/order/credit/buyerOrder")
|
||||
public class CreditBuyerOrderController {
|
||||
private final CreditBuyerOrderService creditBuyerOrderService;
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*/
|
||||
@GetMapping("page")
|
||||
@OperationLog("挂账账单-分页")
|
||||
//@SaAdminCheckPermission("creditBuyerOrder:page")
|
||||
public CzgResult<Page<CreditBuyerOrderDTO>> getCreditBuyerOrderPage(CreditBuyerOrderQueryParam param) {
|
||||
Page<CreditBuyerOrderDTO> data = creditBuyerOrderService.getCreditBuyerOrderPage(param);
|
||||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 付款
|
||||
*/
|
||||
@PostMapping("pay")
|
||||
@OperationLog("挂账账单-付款")
|
||||
//@SaAdminCheckPermission("creditBuyerOrder:pay")
|
||||
public CzgResult<Void> pay(@RequestBody CreditPaymentRecord record) {
|
||||
creditBuyerOrderService.pay(record);
|
||||
return CzgResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计
|
||||
*/
|
||||
@GetMapping("summary")
|
||||
@OperationLog("挂账账单-统计")
|
||||
//@SaAdminCheckPermission("creditBuyerOrder:summary")
|
||||
public CzgResult<CreditBuyerOrderSummaryVo> summary(CreditBuyerOrderQueryParam param) {
|
||||
CreditBuyerOrderSummaryVo data = creditBuyerOrderService.summary(param);
|
||||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.czg.controller.admin;
|
||||
|
||||
import com.czg.log.annotation.OperationLog;
|
||||
import com.czg.order.dto.CreditPaymentRecordDTO;
|
||||
import com.czg.order.param.CreditPaymentRecordQueryParam;
|
||||
import com.czg.order.service.CreditPaymentRecordService;
|
||||
import com.czg.resp.CzgResult;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
|
||||
/**
|
||||
* 挂账账单付款记录
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/admin/order/credit/paymentRecord")
|
||||
public class CreditPaymentRecordController {
|
||||
private final CreditPaymentRecordService creditPaymentRecordService;
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*/
|
||||
@GetMapping("page")
|
||||
@OperationLog("挂账账单付款记录-分页")
|
||||
//@SaAdminCheckPermission("creditPaymentRecord:page")
|
||||
public CzgResult<Page<CreditPaymentRecordDTO>> getCreditPaymentRecordPage(CreditPaymentRecordQueryParam param) {
|
||||
Page<CreditPaymentRecordDTO> data = creditPaymentRecordService.getCreditPaymentRecordPage(param);
|
||||
return CzgResult.success(data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
package com.czg.order.dto;
|
||||
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 挂账人
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Data
|
||||
public class CreditBuyerDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 挂账编码
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Long shopId;
|
||||
/**
|
||||
* 状态 1-启用 0-停用
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 挂账人
|
||||
*/
|
||||
private String debtor;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 职务
|
||||
*/
|
||||
private String position;
|
||||
/**
|
||||
* 挂账额度
|
||||
*/
|
||||
private BigDecimal creditAmount;
|
||||
/**
|
||||
* 账户余额
|
||||
*/
|
||||
private BigDecimal accountBalance;
|
||||
/**
|
||||
* 还款方式 total-按总金额还款 order-按订单还款
|
||||
*/
|
||||
private String repaymentMethod;
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
private String paymentMethod;
|
||||
/**
|
||||
* 责任人
|
||||
*/
|
||||
private String responsiblePerson;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 删除标志 0-正常 1-删除
|
||||
*/
|
||||
private Integer isDel;
|
||||
|
||||
/**
|
||||
* 已挂账金额
|
||||
*/
|
||||
private BigDecimal owedAmount;
|
||||
|
||||
/**
|
||||
* 剩余挂账额度
|
||||
*/
|
||||
private BigDecimal remainingAmount;
|
||||
|
||||
/**
|
||||
* 累计挂账金额
|
||||
*/
|
||||
private BigDecimal accumulateAmount;
|
||||
|
||||
/**
|
||||
* 适用门店
|
||||
*/
|
||||
private String shopName;
|
||||
|
||||
/**
|
||||
* 剩余挂账额度
|
||||
*/
|
||||
public BigDecimal getRemainingAmount() {
|
||||
return NumberUtil.sub(creditAmount, NumberUtil.nullToZero(owedAmount));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package com.czg.order.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 挂账账单
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Data
|
||||
public class CreditBuyerOrderDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 订单id
|
||||
*/
|
||||
private Long orderId;
|
||||
/**
|
||||
* 挂账人编码
|
||||
*/
|
||||
private String creditBuyerId;
|
||||
/**
|
||||
* 应付金额
|
||||
*/
|
||||
private BigDecimal payAmount;
|
||||
/**
|
||||
* 已付金额
|
||||
*/
|
||||
private BigDecimal paidAmount;
|
||||
/**
|
||||
* 未付金额
|
||||
*/
|
||||
private BigDecimal unpaidAmount;
|
||||
/**
|
||||
* 状态 unpaid-未付款 partial-部分支付 paid-已付款
|
||||
*/
|
||||
private String status;
|
||||
/**
|
||||
* 最近一次付款时间
|
||||
*/
|
||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime lastPaymentTime;
|
||||
/**
|
||||
* 最近一次付款方式
|
||||
*/
|
||||
private String lastPaymentMethod;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package com.czg.order.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 挂账账单付款记录
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Data
|
||||
public class CreditPaymentRecordDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 订单id
|
||||
*/
|
||||
private Long orderId;
|
||||
/**
|
||||
* 挂账人编码
|
||||
*/
|
||||
private String creditBuyerId;
|
||||
/**
|
||||
* 还款金额
|
||||
*/
|
||||
private BigDecimal repaymentAmount;
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
private String paymentMethod;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 还款时间
|
||||
*/
|
||||
private LocalDateTime paymentTime;
|
||||
/**
|
||||
* 操作时间
|
||||
*/
|
||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package com.czg.order.entity;
|
||||
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.KeyType;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import com.mybatisflex.core.keygen.KeyGenerators;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 挂账人
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Data
|
||||
@Table("tb_credit_buyer")
|
||||
public class CreditBuyer implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 挂账编码
|
||||
*/
|
||||
@Id(keyType = KeyType.Generator, value = KeyGenerators.snowFlakeId)
|
||||
private String id;
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Long shopId;
|
||||
/**
|
||||
* 状态 1-启用 0-停用
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 挂账人
|
||||
*/
|
||||
private String debtor;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 职务
|
||||
*/
|
||||
private String position;
|
||||
/**
|
||||
* 挂账额度
|
||||
*/
|
||||
private BigDecimal creditAmount;
|
||||
/**
|
||||
* 账户余额
|
||||
*/
|
||||
private BigDecimal accountBalance;
|
||||
/**
|
||||
* 还款方式 total-按总金额还款 order-按订单还款
|
||||
*/
|
||||
private String repaymentMethod;
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
private String paymentMethod;
|
||||
/**
|
||||
* 责任人
|
||||
*/
|
||||
private String responsiblePerson;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 删除标志 0-正常 1-删除
|
||||
*/
|
||||
private Integer isDel;
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package com.czg.order.entity;
|
||||
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.KeyType;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 挂账账单
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Data
|
||||
@Table("tb_credit_buyer_order")
|
||||
public class CreditBuyerOrder implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Long id;
|
||||
/**
|
||||
* 订单id
|
||||
*/
|
||||
private Long orderId;
|
||||
/**
|
||||
* 挂账人编码
|
||||
*/
|
||||
private String creditBuyerId;
|
||||
/**
|
||||
* 已付金额
|
||||
*/
|
||||
private BigDecimal paidAmount;
|
||||
/**
|
||||
* 状态 unpaid-未付款 partial-部分支付 paid-已付款
|
||||
*/
|
||||
private String status;
|
||||
/**
|
||||
* 最近一次付款时间
|
||||
*/
|
||||
private LocalDateTime lastPaymentTime;
|
||||
/**
|
||||
* 最近一次付款方式
|
||||
*/
|
||||
private String lastPaymentMethod;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package com.czg.order.entity;
|
||||
|
||||
import com.mybatisflex.annotation.Column;
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.KeyType;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 挂账账单付款记录
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Data
|
||||
@Table("tb_credit_payment_record")
|
||||
public class CreditPaymentRecord implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Long id;
|
||||
/**
|
||||
* 订单id
|
||||
*/
|
||||
private Long orderId;
|
||||
/**
|
||||
* 挂账人编码
|
||||
*/
|
||||
private String creditBuyerId;
|
||||
/**
|
||||
* 还款金额
|
||||
*/
|
||||
private BigDecimal repaymentAmount;
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
private String paymentMethod;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 还款时间
|
||||
*/
|
||||
private LocalDateTime paymentTime;
|
||||
/**
|
||||
* 操作时间
|
||||
*/
|
||||
@Column(onInsertValue = "now()")
|
||||
private LocalDateTime createTime;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.czg.order.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 挂账还款状态枚举
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-04 17:53
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum CreditBuyerEnums {
|
||||
|
||||
/**
|
||||
* 未还款
|
||||
*/
|
||||
UNPAID("unpaid", "未还款"),
|
||||
|
||||
/**
|
||||
* 部分还款
|
||||
*/
|
||||
PARTIAL("partial", "部分还款"),
|
||||
/**
|
||||
* 已还清
|
||||
*/
|
||||
PAID("paid", "已还清"),
|
||||
|
||||
;
|
||||
|
||||
private final String value;
|
||||
private final String text;
|
||||
|
||||
|
||||
public static List<String> getValues() {
|
||||
return Arrays.stream(values()).map(CreditBuyerEnums::getValue).toList();
|
||||
}
|
||||
|
||||
public static String getText(String value) {
|
||||
CreditBuyerEnums item = Arrays.stream(values()).filter(obj -> value.equals(obj.getValue())).findFirst().orElse(null);
|
||||
if (item != null) {
|
||||
return item.getText();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.czg.order.param;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 挂账订单查询入参
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-05 11:02
|
||||
*/
|
||||
@Data
|
||||
public class CreditBuyerOrderQueryParam implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private Long id;
|
||||
/**
|
||||
* 挂账人id
|
||||
*/
|
||||
private String creditBuyerId;
|
||||
/**
|
||||
* 挂账订单id
|
||||
*/
|
||||
private String orderId;
|
||||
/**
|
||||
* 开始日期 格式:yyyy-MM-dd
|
||||
*/
|
||||
private String beginDate;
|
||||
/**
|
||||
* 结束日期 格式:yyyy-MM-dd
|
||||
*/
|
||||
private String endDate;
|
||||
/**
|
||||
* 订单状态 unpaid-未付款 partial-部分支付 paid-已付款
|
||||
*/
|
||||
private String status;
|
||||
/**
|
||||
* 订单状态集合 unpaid-未付款 partial-部分支付 paid-已付款
|
||||
*/
|
||||
private List<String> statusList;
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.czg.order.param;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 挂账人查询入参
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-04 17:42
|
||||
*/
|
||||
@Data
|
||||
public class CreditBuyerQueryParam implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 挂账编码
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private String id;
|
||||
/**
|
||||
* 关键字
|
||||
*/
|
||||
private String keywords;
|
||||
/**
|
||||
* 还款状态 unpaid-未还款 partial-部分还款 paid-已还清
|
||||
*/
|
||||
private String repaymentStatus;
|
||||
/**
|
||||
* 责任人
|
||||
*/
|
||||
private String responsiblePerson;
|
||||
/**
|
||||
* 状态 1-启用 0-停用
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private Long shopId;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.czg.order.param;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 挂账还款入参
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-04 17:42
|
||||
*/
|
||||
@Data
|
||||
public class CreditBuyerRepaymentParam implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 挂账编码(挂账人id)
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 还款金额
|
||||
*/
|
||||
private BigDecimal repaymentAmount;
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
private String paymentMethod;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.czg.order.param;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 挂账账单付款记录查询入参
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Data
|
||||
public class CreditPaymentRecordQueryParam implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 挂账人编码
|
||||
*/
|
||||
private String creditBuyerId;
|
||||
/**
|
||||
* 订单id
|
||||
*/
|
||||
private Long orderId;
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
private String paymentMethod;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package com.czg.order.service;
|
||||
|
||||
import com.czg.order.dto.CreditBuyerOrderDTO;
|
||||
import com.czg.order.entity.CreditBuyerOrder;
|
||||
import com.czg.order.entity.CreditPaymentRecord;
|
||||
import com.czg.order.param.CreditBuyerOrderQueryParam;
|
||||
import com.czg.order.vo.CreditBuyerOrderSummaryVo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 挂账账单
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
public interface CreditBuyerOrderService extends IService<CreditBuyerOrder> {
|
||||
/**
|
||||
* 分页查询挂账账单
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return 分页结果
|
||||
*/
|
||||
Page<CreditBuyerOrderDTO> getCreditBuyerOrderPage(CreditBuyerOrderQueryParam param);
|
||||
|
||||
/**
|
||||
* 挂账账单汇总
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return 汇总结果
|
||||
*/
|
||||
CreditBuyerOrderSummaryVo summary(CreditBuyerOrderQueryParam param);
|
||||
|
||||
/**
|
||||
* 支付挂账订单
|
||||
*
|
||||
* @param record 入参
|
||||
*/
|
||||
void pay(CreditPaymentRecord record);
|
||||
|
||||
/**
|
||||
* 保存挂账账单
|
||||
*
|
||||
* @param creditBuyerId 挂账人id
|
||||
* @param orderId 订单id
|
||||
*/
|
||||
boolean save(String creditBuyerId, Long orderId);
|
||||
|
||||
/**
|
||||
* 挂账人退款(整单退款)
|
||||
*
|
||||
* @param creditBuyerId 挂账人id
|
||||
* @param orderId 订单id
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
boolean refund(String creditBuyerId, Long orderId);
|
||||
|
||||
|
||||
/**
|
||||
* 挂账人退款(部分退款)
|
||||
*
|
||||
* @param creditBuyerId 挂账人id
|
||||
* @param orderId 订单id
|
||||
* @param refundAmount 退款金额
|
||||
* @return
|
||||
*/
|
||||
boolean partRefund(String creditBuyerId, Long orderId, BigDecimal refundAmount);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.czg.order.service;
|
||||
|
||||
import com.czg.order.dto.CreditBuyerDTO;
|
||||
import com.czg.order.entity.CreditBuyer;
|
||||
import com.czg.order.param.CreditBuyerQueryParam;
|
||||
import com.czg.order.param.CreditBuyerRepaymentParam;
|
||||
import com.czg.order.vo.CreditBuyerRepaymentVo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
|
||||
/**
|
||||
* 挂账人
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
public interface CreditBuyerService extends IService<CreditBuyer> {
|
||||
Page<CreditBuyerDTO> getCreditBuyerPage(CreditBuyerQueryParam param);
|
||||
|
||||
CreditBuyerDTO getCreditBuyerById(String id);
|
||||
|
||||
void addCreditBuyer(CreditBuyerDTO dto);
|
||||
|
||||
void updateCreditBuyer(CreditBuyerDTO dto);
|
||||
|
||||
void deleteCreditBuyer(String id);
|
||||
|
||||
CreditBuyerRepaymentVo repayment(CreditBuyerRepaymentParam param);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.czg.order.service;
|
||||
|
||||
import com.czg.order.dto.CreditPaymentRecordDTO;
|
||||
import com.czg.order.entity.CreditPaymentRecord;
|
||||
import com.czg.order.param.CreditPaymentRecordQueryParam;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
|
||||
/**
|
||||
* 挂账账单付款记录
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
public interface CreditPaymentRecordService extends IService<CreditPaymentRecord> {
|
||||
Page<CreditPaymentRecordDTO> getCreditPaymentRecordPage(CreditPaymentRecordQueryParam param);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.czg.order.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 挂账账单统计结果
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Data
|
||||
public class CreditBuyerOrderSummaryVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 总交易笔数
|
||||
*/
|
||||
private Long count;
|
||||
/**
|
||||
* 总交易金额
|
||||
*/
|
||||
private BigDecimal payAmountTotal;
|
||||
/**
|
||||
* 已支付金额
|
||||
*/
|
||||
private BigDecimal paidAmountTotal;
|
||||
/**
|
||||
* 待支付金额
|
||||
*/
|
||||
private BigDecimal unpaidAmountTotal;
|
||||
/**
|
||||
* 待支付笔数
|
||||
*/
|
||||
private Long unpaidCount;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.czg.order.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 挂账还款出参
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-04 17:42
|
||||
*/
|
||||
@Data
|
||||
public class CreditBuyerRepaymentVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 还款笔数
|
||||
*/
|
||||
private Integer repaymentCount;
|
||||
/**
|
||||
* 还款金额
|
||||
*/
|
||||
private BigDecimal repaymentAmount;
|
||||
/**
|
||||
* 支付欠款
|
||||
*/
|
||||
private BigDecimal payAmount;
|
||||
/**
|
||||
* 转存金额
|
||||
*/
|
||||
private BigDecimal rechargeAmount;
|
||||
/**
|
||||
* 还款反馈消息
|
||||
*/
|
||||
private String repaymentMsg;
|
||||
}
|
||||
|
|
@ -6,7 +6,13 @@ package com.czg.enums;
|
|||
* @since 2025-02-11 14:54
|
||||
*/
|
||||
public enum StatusEnum {
|
||||
/**
|
||||
* 禁用状态
|
||||
*/
|
||||
DISABLE(0),
|
||||
/**
|
||||
* 启用状态
|
||||
*/
|
||||
ENABLED(1);
|
||||
|
||||
private final int value;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.czg.utils;
|
|||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.github.pagehelper.PageParam;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
|
@ -63,7 +64,7 @@ public class PageUtil {
|
|||
|
||||
/**
|
||||
* 构造排序QueryWrapper
|
||||
* 从param体获取
|
||||
* 从param体获取
|
||||
* <p>
|
||||
* orderField 排序字段列 驼峰命名 多个用逗号分隔
|
||||
* order排序规则 asc,desc 多个条件逗号分割
|
||||
|
|
@ -79,6 +80,25 @@ public class PageUtil {
|
|||
return queryWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* pageHelper 分页参数构造
|
||||
*
|
||||
* @return PageParam
|
||||
*/
|
||||
public PageParam buildPageHelp() {
|
||||
HttpServletRequest request = ServletUtil.getRequest();
|
||||
Integer pageNum = Convert.toInt(request.getParameter(PAGE), DEFAULT_PAGE);
|
||||
Integer pageSize = Convert.toInt(request.getParameter(SIZE), DEFAULT_SIZE);
|
||||
String orderBy = ServletUtil.getRequest().getParameter(ORDER_BY);
|
||||
PageParam pageParam = new PageParam();
|
||||
pageParam.setPageNum(pageNum);
|
||||
pageParam.setPageSize(pageSize);
|
||||
if (StrUtil.isNotEmpty(orderBy)) {
|
||||
pageParam.setOrderBy(SqlUtil.escapeOrderBySql(orderBy));
|
||||
}
|
||||
return pageParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* pageHelper 转为 mybatisflex 分页
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
package com.czg.service.order.mapper;
|
||||
|
||||
import com.czg.order.dto.CreditBuyerDTO;
|
||||
import com.czg.order.entity.CreditBuyer;
|
||||
import com.czg.order.param.CreditBuyerQueryParam;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 挂账人
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Mapper
|
||||
public interface CreditBuyerMapper extends BaseMapper<CreditBuyer> {
|
||||
|
||||
List<CreditBuyerDTO> findCreditBuyerList(CreditBuyerQueryParam param);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.czg.service.order.mapper;
|
||||
|
||||
import com.czg.order.dto.CreditBuyerOrderDTO;
|
||||
import com.czg.order.entity.CreditBuyerOrder;
|
||||
import com.czg.order.param.CreditBuyerOrderQueryParam;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 挂账账单
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Mapper
|
||||
public interface CreditBuyerOrderMapper extends BaseMapper<CreditBuyerOrder> {
|
||||
|
||||
List<CreditBuyerOrderDTO> findCreditBuyerOrderList(CreditBuyerOrderQueryParam param);
|
||||
|
||||
long getCreditBuyerOrderCount(CreditBuyerOrderQueryParam param);
|
||||
|
||||
BigDecimal getSumPayAmount(CreditBuyerOrderQueryParam param);
|
||||
|
||||
BigDecimal getSumPaidAmount(CreditBuyerOrderQueryParam param);
|
||||
|
||||
BigDecimal getSumUnpaidAmount(CreditBuyerOrderQueryParam param);
|
||||
|
||||
CreditBuyerOrderDTO getOne(CreditBuyerOrderQueryParam param);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.czg.service.order.mapper;
|
||||
|
||||
import com.czg.order.entity.CreditPaymentRecord;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 挂账账单付款记录
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Mapper
|
||||
public interface CreditPaymentRecordMapper extends BaseMapper<CreditPaymentRecord> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,337 @@
|
|||
package com.czg.service.order.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.czg.enums.DeleteEnum;
|
||||
import com.czg.exception.CzgException;
|
||||
import com.czg.order.dto.CreditBuyerDTO;
|
||||
import com.czg.order.dto.CreditBuyerOrderDTO;
|
||||
import com.czg.order.entity.CreditBuyer;
|
||||
import com.czg.order.entity.CreditBuyerOrder;
|
||||
import com.czg.order.entity.CreditPaymentRecord;
|
||||
import com.czg.order.entity.OrderInfo;
|
||||
import com.czg.order.param.CreditBuyerOrderQueryParam;
|
||||
import com.czg.order.service.CreditBuyerOrderService;
|
||||
import com.czg.order.service.CreditBuyerService;
|
||||
import com.czg.order.vo.CreditBuyerOrderSummaryVo;
|
||||
import com.czg.service.order.mapper.CreditBuyerMapper;
|
||||
import com.czg.service.order.mapper.CreditBuyerOrderMapper;
|
||||
import com.czg.service.order.mapper.CreditPaymentRecordMapper;
|
||||
import com.czg.service.order.mapper.OrderInfoMapper;
|
||||
import com.czg.utils.PageUtil;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.github.pagehelper.PageParam;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.update.UpdateChain;
|
||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 挂账账单
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Service
|
||||
public class CreditBuyerOrderServiceImpl extends ServiceImpl<CreditBuyerOrderMapper, CreditBuyerOrder> implements CreditBuyerOrderService {
|
||||
|
||||
@Resource
|
||||
private CreditBuyerMapper creditBuyerMapper;
|
||||
@Resource
|
||||
private CreditPaymentRecordMapper creditPaymentRecordMapper;
|
||||
@Resource
|
||||
@Lazy
|
||||
private CreditBuyerService creditBuyerService;
|
||||
@Resource
|
||||
private OrderInfoMapper orderInfoMapper;
|
||||
|
||||
@Override
|
||||
public Page<CreditBuyerOrderDTO> getCreditBuyerOrderPage(CreditBuyerOrderQueryParam param) {
|
||||
PageParam pageParam = PageUtil.buildPageHelp();
|
||||
PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize(), StrUtil.blankToDefault(pageParam.getOrderBy(), "order_id desc"));
|
||||
PageInfo<CreditBuyerOrderDTO> pageInfo = new PageInfo<>(super.mapper.findCreditBuyerOrderList(param));
|
||||
return PageUtil.convert(pageInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreditBuyerOrderSummaryVo summary(CreditBuyerOrderQueryParam param) {
|
||||
CreditBuyerOrderSummaryVo data = new CreditBuyerOrderSummaryVo();
|
||||
long count = super.mapper.getCreditBuyerOrderCount(param);
|
||||
// 总交易笔数
|
||||
data.setCount(count);
|
||||
// 总交易金额
|
||||
BigDecimal payAmount = super.mapper.getSumPayAmount(param);
|
||||
data.setPayAmountTotal(payAmount);
|
||||
|
||||
// 待支付笔数
|
||||
param.setStatusList(List.of("unpaid", "partial"));
|
||||
long unpaidCount = super.mapper.getCreditBuyerOrderCount(param);
|
||||
data.setUnpaidCount(unpaidCount);
|
||||
param.setStatusList(List.of("paid", "partial"));
|
||||
BigDecimal paidAmount = super.mapper.getSumPaidAmount(param);
|
||||
param.setStatusList(List.of("unpaid", "partial"));
|
||||
BigDecimal unpaidAmount = super.mapper.getSumUnpaidAmount(param);
|
||||
data.setPaidAmountTotal(paidAmount);
|
||||
data.setUnpaidAmountTotal(unpaidAmount);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void pay(CreditPaymentRecord record) {
|
||||
try {
|
||||
Assert.notNull(record.getCreditBuyerId(), "{}({})不能为空", "挂账人id", "creditBuyerId");
|
||||
Assert.notNull(record.getOrderId(), "{}({})不能为空", "订单id", "orderId");
|
||||
Assert.notNull(record.getRepaymentAmount(), "{}({})不能为空", "还款金额", "repaymentAmount");
|
||||
Assert.notEmpty(record.getPaymentMethod(), "{}({})不能为空", "支付方式", "paymentMethod");
|
||||
//Assert.notNull(record.getPaymentTime(), "{}({})不能为空", "还款时间", "paymentTime");
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new CzgException(e.getMessage());
|
||||
}
|
||||
CreditBuyer creditBuyer = creditBuyerMapper.selectOneById(record.getCreditBuyerId());
|
||||
if (creditBuyer == null) {
|
||||
throw new CzgException("挂账人不存在");
|
||||
}
|
||||
String repaymentMethod = creditBuyer.getRepaymentMethod();
|
||||
if (!"order".equals(repaymentMethod)) {
|
||||
throw new CzgException("该挂账人不支持按订单付款");
|
||||
}
|
||||
CreditBuyerOrderQueryParam param = new CreditBuyerOrderQueryParam();
|
||||
param.setCreditBuyerId(record.getCreditBuyerId());
|
||||
param.setOrderId(Convert.toStr(record.getOrderId()));
|
||||
CreditBuyerOrderDTO dto = super.mapper.getOne(param);
|
||||
if (dto == null) {
|
||||
throw new CzgException("挂账订单不存在");
|
||||
}
|
||||
if ("paid".equals(dto.getStatus())) {
|
||||
throw new CzgException("挂账订单已还清,无需还款");
|
||||
}
|
||||
if (NumberUtil.isLess(record.getRepaymentAmount(), BigDecimal.ZERO)) {
|
||||
throw new CzgException("还款金额不能小于0");
|
||||
}
|
||||
if (NumberUtil.isGreater(record.getRepaymentAmount(), dto.getUnpaidAmount())) {
|
||||
throw new CzgException("还款金额不能大于未支付金额");
|
||||
}
|
||||
CreditBuyerOrder entity = BeanUtil.copyProperties(dto, CreditBuyerOrder.class);
|
||||
if (NumberUtil.equals(record.getRepaymentAmount(), dto.getUnpaidAmount())) {
|
||||
entity.setStatus("paid");
|
||||
} else {
|
||||
entity.setStatus("partial");
|
||||
}
|
||||
entity.setPaidAmount(NumberUtil.add(entity.getPaidAmount(), record.getRepaymentAmount()));
|
||||
entity.setLastPaymentTime(LocalDateTime.now());
|
||||
entity.setLastPaymentMethod(record.getPaymentMethod());
|
||||
entity.setRemark(record.getRemark());
|
||||
super.updateById(entity);
|
||||
record.setPaymentTime(LocalDateTime.now());
|
||||
creditPaymentRecordMapper.insert(record);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean save(String creditBuyerId, Long orderId) {
|
||||
if (StrUtil.isBlank(creditBuyerId)) {
|
||||
throw new CzgException("挂账人id不能为空");
|
||||
}
|
||||
CreditBuyerDTO creditBuyer = creditBuyerService.getCreditBuyerById(creditBuyerId);
|
||||
if (creditBuyer == null) {
|
||||
throw new CzgException("挂账人不存在");
|
||||
}
|
||||
Integer delFlag = creditBuyer.getIsDel();
|
||||
if (delFlag != null && delFlag == DeleteEnum.DELETED.value()) {
|
||||
throw new CzgException("挂账人已删除");
|
||||
}
|
||||
Integer status = creditBuyer.getStatus();
|
||||
if (status != null && status == DeleteEnum.NORMAL.value()) {
|
||||
throw new CzgException("挂账人已被停用");
|
||||
}
|
||||
OrderInfo orderInfo = orderInfoMapper.selectOneById(orderId);
|
||||
if (orderInfo == null) {
|
||||
throw new CzgException("订单不存在");
|
||||
}
|
||||
// 账户余额
|
||||
BigDecimal accountBalance = creditBuyer.getAccountBalance();
|
||||
// 如果有余额的话,从余额里面扣除,没有余额的话,从信用额度里面扣除,余额和信用额度都为0,则不允许挂账,余额+信用额度刚好够支付这笔订单的话需要同时减余额减信用额度
|
||||
if (NumberUtil.isGreaterOrEqual(accountBalance, orderInfo.getOrderAmount())) {
|
||||
// 减余额
|
||||
creditBuyer.setAccountBalance(NumberUtil.sub(accountBalance, orderInfo.getOrderAmount()));
|
||||
CreditBuyer dbRecord = BeanUtil.copyProperties(creditBuyer, CreditBuyer.class);
|
||||
creditBuyerMapper.update(dbRecord);
|
||||
// 记录还款记录
|
||||
CreditPaymentRecord record = new CreditPaymentRecord();
|
||||
record.setCreditBuyerId(creditBuyerId);
|
||||
record.setOrderId(orderId);
|
||||
record.setRepaymentAmount(orderInfo.getOrderAmount());
|
||||
record.setPaymentMethod("余额支付");
|
||||
record.setPaymentTime(LocalDateTime.now());
|
||||
record.setRemark("挂账时余额充足,直接从余额扣除");
|
||||
creditPaymentRecordMapper.insert(record);
|
||||
CreditBuyerOrder entity = new CreditBuyerOrder();
|
||||
entity.setCreditBuyerId(creditBuyerId);
|
||||
entity.setOrderId(orderId);
|
||||
entity.setPaidAmount(orderInfo.getOrderAmount());
|
||||
entity.setStatus("paid");
|
||||
entity.setLastPaymentTime(LocalDateTime.now());
|
||||
entity.setLastPaymentMethod(record.getPaymentMethod());
|
||||
entity.setRemark(record.getRemark());
|
||||
return super.save(entity);
|
||||
}
|
||||
CreditBuyerOrder entity = null;
|
||||
if (NumberUtil.isGreater(accountBalance, BigDecimal.ZERO)) {
|
||||
// 减余额
|
||||
creditBuyer.setAccountBalance(BigDecimal.ZERO);
|
||||
CreditBuyer dbRecord = BeanUtil.copyProperties(creditBuyer, CreditBuyer.class);
|
||||
creditBuyerMapper.update(dbRecord);
|
||||
// 记录还款记录
|
||||
CreditPaymentRecord record = new CreditPaymentRecord();
|
||||
record.setCreditBuyerId(creditBuyerId);
|
||||
record.setOrderId(orderId);
|
||||
record.setRepaymentAmount(accountBalance);
|
||||
record.setPaymentMethod("余额支付");
|
||||
record.setPaymentTime(LocalDateTime.now());
|
||||
record.setRemark("挂账时余额不足,先扣除现有余额,其他的从挂账额度中扣除");
|
||||
creditPaymentRecordMapper.insert(record);
|
||||
entity = new CreditBuyerOrder();
|
||||
entity.setCreditBuyerId(creditBuyerId);
|
||||
entity.setOrderId(orderId);
|
||||
entity.setPaidAmount(accountBalance);
|
||||
entity.setStatus("partial");
|
||||
entity.setLastPaymentTime(LocalDateTime.now());
|
||||
entity.setLastPaymentMethod(record.getPaymentMethod());
|
||||
entity.setRemark(record.getRemark());
|
||||
//super.save(entity);
|
||||
orderInfo.setPayAmount(NumberUtil.sub(orderInfo.getOrderAmount(), accountBalance));
|
||||
}
|
||||
// 剩余挂账额度
|
||||
BigDecimal remainingAmount = creditBuyer.getRemainingAmount();
|
||||
// 验证挂账金额是否大于剩余额度
|
||||
boolean greater = NumberUtil.isGreater(orderInfo.getOrderAmount(), remainingAmount);
|
||||
if (greater) {
|
||||
throw new CzgException(StrUtil.format("{}:¥{}不能大于剩余挂账额度({})", "挂账金额", orderInfo.getOrderAmount(), remainingAmount));
|
||||
}
|
||||
if (entity == null) {
|
||||
entity = new CreditBuyerOrder();
|
||||
entity.setStatus("unpaid");
|
||||
entity.setPaidAmount(BigDecimal.ZERO);
|
||||
entity.setCreditBuyerId(creditBuyerId);
|
||||
entity.setOrderId(orderId);
|
||||
}
|
||||
return super.saveOrUpdate(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean refund(String creditBuyerId, Long orderId) {
|
||||
if (StrUtil.isBlank(creditBuyerId)) {
|
||||
throw new CzgException("挂账人id不能为空");
|
||||
}
|
||||
CreditBuyer creditBuyer = creditBuyerService.getById(creditBuyerId);
|
||||
if (creditBuyer == null) {
|
||||
throw new CzgException("挂账人不存在");
|
||||
}
|
||||
OrderInfo orderInfo = orderInfoMapper.selectOneById(orderId);
|
||||
if (orderInfo == null) {
|
||||
throw new CzgException("订单不存在");
|
||||
}
|
||||
|
||||
CreditBuyerOrderQueryParam param = new CreditBuyerOrderQueryParam();
|
||||
param.setCreditBuyerId(creditBuyerId);
|
||||
param.setOrderId(Convert.toStr(orderId));
|
||||
CreditBuyerOrderDTO dto = super.mapper.getOne(param);
|
||||
if (dto == null) {
|
||||
throw new CzgException("挂账订单不存在");
|
||||
}
|
||||
// 1.只挂账未还款的情况,直接删除挂账订单
|
||||
if ("unpaid".equals(dto.getStatus())) {
|
||||
super.mapper.deleteById(dto.getId());
|
||||
return true;
|
||||
}
|
||||
// 2.部分还款/已还款,删除挂账订单+红冲还款记录,并把已还款金额退回余额或挂账额度
|
||||
if ("partial".equals(dto.getStatus()) || "paid".equals(dto.getStatus())) {
|
||||
// 已还款金额
|
||||
BigDecimal paidAmount = dto.getPaidAmount();
|
||||
// 已还款金额进行红冲
|
||||
CreditPaymentRecord record = new CreditPaymentRecord();
|
||||
record.setCreditBuyerId(creditBuyerId);
|
||||
record.setOrderId(orderId);
|
||||
record.setRepaymentAmount(NumberUtil.sub(BigDecimal.ZERO, paidAmount));
|
||||
record.setPaymentMethod("挂账退款");
|
||||
record.setPaymentTime(LocalDateTime.now());
|
||||
record.setRemark(StrUtil.format("挂账订单:{}申请退款,已归还挂账额度或账户余额", orderInfo.getOrderNo()));
|
||||
creditPaymentRecordMapper.insert(record);
|
||||
// 删除挂账订单,恢复挂账额度
|
||||
super.mapper.deleteById(dto.getId());
|
||||
// 退回余额
|
||||
creditBuyer.setAccountBalance(NumberUtil.add(creditBuyer.getAccountBalance(), paidAmount));
|
||||
creditBuyerService.updateById(creditBuyer);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean partRefund(String creditBuyerId, Long orderId, BigDecimal refundAmount) {
|
||||
if (StrUtil.isBlank(creditBuyerId)) {
|
||||
throw new CzgException("挂账人id不能为空");
|
||||
}
|
||||
CreditBuyerDTO creditBuyer = creditBuyerService.getCreditBuyerById(creditBuyerId);
|
||||
if (creditBuyer == null) {
|
||||
throw new CzgException("挂账人不存在");
|
||||
}
|
||||
OrderInfo orderInfo = orderInfoMapper.selectOneById(orderId);
|
||||
if (orderInfo == null) {
|
||||
throw new CzgException("订单不存在");
|
||||
}
|
||||
|
||||
CreditBuyerOrderQueryParam param = new CreditBuyerOrderQueryParam();
|
||||
param.setCreditBuyerId(creditBuyerId);
|
||||
param.setOrderId(Convert.toStr(orderId));
|
||||
CreditBuyerOrderDTO dto = mapper.getOne(param);
|
||||
if (dto == null) {
|
||||
throw new CzgException("挂账订单不存在");
|
||||
}
|
||||
// 已还款金额进行红冲
|
||||
CreditPaymentRecord record = new CreditPaymentRecord();
|
||||
record.setCreditBuyerId(creditBuyerId);
|
||||
record.setOrderId(orderId);
|
||||
record.setRepaymentAmount(NumberUtil.sub(BigDecimal.ZERO, refundAmount));
|
||||
record.setPaymentMethod("挂账退款");
|
||||
record.setPaymentTime(LocalDateTime.now());
|
||||
record.setRemark(StrUtil.format("挂账订单:{},申请退款¥{}元,已恢复挂账额度。", orderInfo.getOrderNo(), refundAmount));
|
||||
creditPaymentRecordMapper.insert(record);
|
||||
dto = mapper.getOne(param);
|
||||
BigDecimal sub = NumberUtil.sub(refundAmount, dto.getUnpaidAmount());
|
||||
if (NumberUtil.isGreater(sub, BigDecimal.ZERO)) {
|
||||
CreditPaymentRecord flow = new CreditPaymentRecord();
|
||||
flow.setCreditBuyerId(creditBuyerId);
|
||||
flow.setOrderId(orderId);
|
||||
flow.setRepaymentAmount(sub);
|
||||
flow.setPaymentMethod("转储余额");
|
||||
flow.setPaymentTime(LocalDateTime.now());
|
||||
flow.setRemark(StrUtil.format("挂账订单:{},申请退款¥{}元,由于此挂账订单已提前还款,溢出部分¥{}元将转储至账户余额。", orderInfo.getOrderNo(), refundAmount, sub));
|
||||
creditPaymentRecordMapper.insert(flow);
|
||||
UpdateChain.of(CreditBuyerOrder.class)
|
||||
.set(CreditBuyerOrder::getPaidAmount, NumberUtil.sub(dto.getPaidAmount(), sub))
|
||||
.eq(CreditBuyerOrder::getId, dto.getId())
|
||||
.update();
|
||||
// 退回余额
|
||||
creditBuyer.setAccountBalance(NumberUtil.add(creditBuyer.getAccountBalance(), sub));
|
||||
CreditBuyer entity = BeanUtil.copyProperties(dto, CreditBuyer.class);
|
||||
creditBuyerService.updateById(entity);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,278 @@
|
|||
package com.czg.service.order.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.Validator;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.czg.enums.DeleteEnum;
|
||||
import com.czg.enums.StatusEnum;
|
||||
import com.czg.exception.CzgException;
|
||||
import com.czg.order.dto.CreditBuyerDTO;
|
||||
import com.czg.order.dto.CreditBuyerOrderDTO;
|
||||
import com.czg.order.entity.CreditBuyer;
|
||||
import com.czg.order.entity.CreditBuyerOrder;
|
||||
import com.czg.order.entity.CreditPaymentRecord;
|
||||
import com.czg.order.param.CreditBuyerOrderQueryParam;
|
||||
import com.czg.order.param.CreditBuyerQueryParam;
|
||||
import com.czg.order.param.CreditBuyerRepaymentParam;
|
||||
import com.czg.order.service.CreditBuyerService;
|
||||
import com.czg.order.vo.CreditBuyerRepaymentVo;
|
||||
import com.czg.sa.StpKit;
|
||||
import com.czg.service.order.mapper.CreditBuyerMapper;
|
||||
import com.czg.service.order.mapper.CreditBuyerOrderMapper;
|
||||
import com.czg.service.order.mapper.CreditPaymentRecordMapper;
|
||||
import com.czg.utils.PageUtil;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.github.pagehelper.PageParam;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.update.UpdateChain;
|
||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 挂账人
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Service
|
||||
public class CreditBuyerServiceImpl extends ServiceImpl<CreditBuyerMapper, CreditBuyer> implements CreditBuyerService {
|
||||
|
||||
@Resource
|
||||
private CreditPaymentRecordMapper creditPaymentRecordMapper;
|
||||
@Resource
|
||||
private CreditBuyerOrderMapper creditBuyerOrderMapper;
|
||||
|
||||
@Override
|
||||
public Page<CreditBuyerDTO> getCreditBuyerPage(CreditBuyerQueryParam param) {
|
||||
PageParam pageParam = PageUtil.buildPageHelp();
|
||||
PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getOrderBy());
|
||||
PageInfo<CreditBuyerDTO> pageInfo = new PageInfo<>(super.mapper.findCreditBuyerList(param));
|
||||
return PageUtil.convert(pageInfo);
|
||||
}
|
||||
|
||||
private void commonVerify(CreditBuyerDTO dto) {
|
||||
try {
|
||||
Assert.notNull(dto.getShopId(), "{}({})不能为空", "店铺id", "shopId");
|
||||
Assert.notNull(dto.getStatus(), "{}({})不能为空", "状态", "status");
|
||||
Assert.notEmpty(dto.getDebtor(), "{}({})不能为空", "挂账人", "debtor");
|
||||
Assert.notEmpty(dto.getMobile(), "{}({})不能为空", "手机号", "mobile");
|
||||
Assert.notNull(dto.getCreditAmount(), "{}({})不能为空", "挂账额度", "creditAmount");
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new CzgException(e.getMessage());
|
||||
}
|
||||
if (!Validator.isMobile(dto.getMobile())) {
|
||||
throw new CzgException(StrUtil.format("{}({})不合法", "手机号", "mobile"));
|
||||
}
|
||||
if (NumberUtil.isLessOrEqual(dto.getCreditAmount(), BigDecimal.ZERO)) {
|
||||
throw new CzgException(StrUtil.format("{}({})必须大于0", "挂账额度", "creditAmount"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreditBuyerDTO getCreditBuyerById(String id) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
CreditBuyerQueryParam param = new CreditBuyerQueryParam();
|
||||
param.setId(id);
|
||||
param.setShopId(shopId);
|
||||
List<CreditBuyerDTO> list = super.mapper.findCreditBuyerList(param);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return null;
|
||||
}
|
||||
return list.getFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCreditBuyer(CreditBuyerDTO dto) {
|
||||
commonVerify(dto);
|
||||
try {
|
||||
Assert.notEmpty(dto.getRepaymentMethod(), "{}({})不能为空", "还款方式", "repaymentMethod");
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new CzgException(e.getMessage());
|
||||
}
|
||||
if (!ArrayUtil.contains(new String[]{"total", "order"}, dto.getRepaymentMethod())) {
|
||||
throw new CzgException(StrUtil.format("{}({})不合法", "还款方式", "repaymentMethod"));
|
||||
}
|
||||
dto.setAccountBalance(BigDecimal.ZERO);
|
||||
CreditBuyer entity = BeanUtil.copyProperties(dto, CreditBuyer.class);
|
||||
super.save(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCreditBuyer(CreditBuyerDTO dto) {
|
||||
try {
|
||||
Assert.notEmpty(dto.getId(), "{}不能为空", "id");
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new CzgException(e.getMessage());
|
||||
}
|
||||
commonVerify(dto);
|
||||
CreditBuyer entity = getById(dto.getId());
|
||||
if (entity == null) {
|
||||
throw new CzgException("挂账人不存在");
|
||||
}
|
||||
CreditBuyerDTO record = getCreditBuyerById(dto.getId());
|
||||
// 验证挂账额度是否小于已挂账金额
|
||||
boolean less = NumberUtil.isLess(dto.getCreditAmount(), NumberUtil.nullToZero(record.getOwedAmount()));
|
||||
if (less) {
|
||||
throw new CzgException(StrUtil.format("{}({})不能小于已挂账金额({})", "挂账额度", "creditAmount", record.getOwedAmount()));
|
||||
}
|
||||
BeanUtil.copyProperties(dto, entity, CopyOptions.create().setIgnoreNullValue(false).setIgnoreProperties("repaymentMethod", "accountBalance"));
|
||||
super.updateById(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCreditBuyer(String id) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
UpdateChain.of(CreditBuyer.class)
|
||||
.set(CreditBuyer::getIsDel, StatusEnum.DISABLE.value())
|
||||
.eq(CreditBuyer::getId, id)
|
||||
.eq(CreditBuyer::getShopId, shopId)
|
||||
.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public CreditBuyerRepaymentVo repayment(CreditBuyerRepaymentParam param) {
|
||||
// 还款金额
|
||||
BigDecimal repaymentAmount = param.getRepaymentAmount();
|
||||
try {
|
||||
Assert.notEmpty(param.getId(), "{}不能为空", "id");
|
||||
Assert.notNull(repaymentAmount, "{}({})不能为空", "还款金额", "repaymentAmount");
|
||||
Assert.notNull(param.getPaymentMethod(), "{}({})不能为空", "支付方式", "paymentMethod");
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new CzgException(e.getMessage());
|
||||
}
|
||||
CreditBuyerDTO dto = getCreditBuyerById(param.getId());
|
||||
if (dto == null) {
|
||||
throw new CzgException("挂账人不存在");
|
||||
}
|
||||
Integer isDel = dto.getIsDel();
|
||||
if (isDel == DeleteEnum.DELETED.value()) {
|
||||
throw new CzgException("挂账人已删除");
|
||||
}
|
||||
if (!"total".equals(dto.getRepaymentMethod())) {
|
||||
throw new CzgException("此挂账人不能以【按总账户还款】进行还款");
|
||||
}
|
||||
if (NumberUtil.isLess(repaymentAmount, BigDecimal.ZERO)) {
|
||||
throw new CzgException("还款金额不能小于0");
|
||||
}
|
||||
BigDecimal initRepaymentAmount = NumberUtil.add(repaymentAmount, BigDecimal.ZERO);
|
||||
// 已挂账金额
|
||||
BigDecimal owedAmount = dto.getOwedAmount();
|
||||
if (NumberUtil.equals(owedAmount, BigDecimal.ZERO)) {
|
||||
dto.setAccountBalance(NumberUtil.add(dto.getAccountBalance(), repaymentAmount));
|
||||
CreditBuyer entity = BeanUtil.copyProperties(dto, CreditBuyer.class);
|
||||
super.updateById(entity);
|
||||
CreditPaymentRecord record = new CreditPaymentRecord();
|
||||
record.setCreditBuyerId(param.getId());
|
||||
record.setRepaymentAmount(repaymentAmount);
|
||||
record.setPaymentMethod(param.getPaymentMethod());
|
||||
record.setPaymentTime(LocalDateTime.now());
|
||||
record.setRemark(param.getRemark());
|
||||
creditPaymentRecordMapper.insert(record);
|
||||
CreditBuyerRepaymentVo result = new CreditBuyerRepaymentVo();
|
||||
result.setRepaymentCount(0);
|
||||
result.setRepaymentAmount(repaymentAmount);
|
||||
result.setRepaymentMsg(StrUtil.format("账单无需还款,{}元已转储至余额。", repaymentAmount));
|
||||
return result;
|
||||
}
|
||||
// 转存余额
|
||||
BigDecimal rechargeAmount = BigDecimal.ZERO;
|
||||
if (NumberUtil.isGreater(repaymentAmount, owedAmount)) {
|
||||
rechargeAmount = NumberUtil.sub(repaymentAmount, owedAmount);
|
||||
dto.setAccountBalance(NumberUtil.add(dto.getAccountBalance(), rechargeAmount));
|
||||
CreditBuyer entity = BeanUtil.copyProperties(dto, CreditBuyer.class);
|
||||
super.updateById(entity);
|
||||
CreditPaymentRecord record = new CreditPaymentRecord();
|
||||
record.setCreditBuyerId(param.getId());
|
||||
record.setRepaymentAmount(rechargeAmount);
|
||||
record.setPaymentMethod(param.getPaymentMethod());
|
||||
record.setPaymentTime(LocalDateTime.now());
|
||||
record.setRemark(param.getRemark());
|
||||
creditPaymentRecordMapper.insert(record);
|
||||
}
|
||||
|
||||
// 校验完毕,可以批量还款
|
||||
|
||||
CreditBuyerOrderQueryParam where = new CreditBuyerOrderQueryParam();
|
||||
where.setCreditBuyerId(param.getId());
|
||||
where.setStatusList(List.of("unpaid", "partial"));
|
||||
List<CreditBuyerOrderDTO> list = creditBuyerOrderMapper.findCreditBuyerOrderList(where);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
throw new CzgException("没有需要还款的订单");
|
||||
}
|
||||
int repaymentCount = 0;
|
||||
List<CreditBuyerOrderDTO> orderList = list.stream().sorted(Comparator.comparing(CreditBuyerOrderDTO::getOrderId)).collect(Collectors.toList());
|
||||
for (CreditBuyerOrderDTO item : orderList) {
|
||||
// 未付款金额
|
||||
BigDecimal unpaidAmount = item.getUnpaidAmount();
|
||||
// 记录还款记录
|
||||
CreditPaymentRecord record = new CreditPaymentRecord();
|
||||
if (NumberUtil.isGreaterOrEqual(repaymentAmount, unpaidAmount)) {
|
||||
// 还全额
|
||||
UpdateChain.of(CreditBuyerOrder.class)
|
||||
.set(CreditBuyerOrder::getStatus, "paid")
|
||||
.set(CreditBuyerOrder::getPaidAmount, NumberUtil.add(item.getPaidAmount(), unpaidAmount))
|
||||
.set(CreditBuyerOrder::getRemark, param.getRemark())
|
||||
.set(CreditBuyerOrder::getLastPaymentMethod, param.getPaymentMethod())
|
||||
.set(CreditBuyerOrder::getLastPaymentTime, LocalDateTime.now())
|
||||
.eq(CreditBuyerOrder::getStatus, item.getStatus())
|
||||
.eq(CreditBuyerOrder::getId, item.getId())
|
||||
.eq(CreditBuyerOrder::getOrderId, item.getOrderId())
|
||||
.eq(CreditBuyerOrder::getCreditBuyerId, item.getCreditBuyerId())
|
||||
.eq(CreditBuyerOrder::getPaidAmount, item.getPaidAmount())
|
||||
.update();
|
||||
record.setRepaymentAmount(unpaidAmount);
|
||||
repaymentAmount = NumberUtil.sub(repaymentAmount, unpaidAmount);
|
||||
} else if (NumberUtil.isLess(repaymentAmount, unpaidAmount)) {
|
||||
// 还部分
|
||||
UpdateChain.of(CreditBuyerOrder.class)
|
||||
.set(CreditBuyerOrder::getStatus, "partial")
|
||||
.set(CreditBuyerOrder::getPaidAmount, NumberUtil.add(item.getPaidAmount(), repaymentAmount))
|
||||
.set(CreditBuyerOrder::getRemark, param.getRemark())
|
||||
.set(CreditBuyerOrder::getLastPaymentMethod, param.getPaymentMethod())
|
||||
.set(CreditBuyerOrder::getLastPaymentTime, LocalDateTime.now())
|
||||
.eq(CreditBuyerOrder::getStatus, item.getStatus())
|
||||
.eq(CreditBuyerOrder::getId, item.getId())
|
||||
.eq(CreditBuyerOrder::getOrderId, item.getOrderId())
|
||||
.eq(CreditBuyerOrder::getCreditBuyerId, item.getCreditBuyerId())
|
||||
.eq(CreditBuyerOrder::getPaidAmount, item.getPaidAmount())
|
||||
.update();
|
||||
record.setRepaymentAmount(repaymentAmount);
|
||||
repaymentAmount = BigDecimal.ZERO;
|
||||
}
|
||||
record.setCreditBuyerId(item.getCreditBuyerId());
|
||||
record.setOrderId(item.getOrderId());
|
||||
record.setPaymentMethod(param.getPaymentMethod());
|
||||
record.setPaymentTime(LocalDateTime.now());
|
||||
record.setRemark(param.getRemark());
|
||||
creditPaymentRecordMapper.insert(record);
|
||||
repaymentCount++;
|
||||
if (NumberUtil.equals(repaymentAmount, BigDecimal.ZERO)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
CreditBuyerRepaymentVo result = new CreditBuyerRepaymentVo();
|
||||
BigDecimal payAmount = NumberUtil.sub(initRepaymentAmount, repaymentAmount);
|
||||
result.setRepaymentCount(repaymentCount);
|
||||
result.setRepaymentAmount(initRepaymentAmount);
|
||||
result.setPayAmount(payAmount);
|
||||
result.setRechargeAmount(rechargeAmount);
|
||||
result.setRepaymentMsg(StrUtil.format("共计还款{}笔,还款金额:{}元,支付欠款:{}元,转存余额:{}元,当前余额:{}元。", repaymentCount, initRepaymentAmount, payAmount, rechargeAmount, dto.getAccountBalance()));
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.czg.service.order.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.czg.order.dto.CreditPaymentRecordDTO;
|
||||
import com.czg.order.entity.CreditPaymentRecord;
|
||||
import com.czg.order.param.CreditPaymentRecordQueryParam;
|
||||
import com.czg.order.service.CreditPaymentRecordService;
|
||||
import com.czg.service.order.mapper.CreditPaymentRecordMapper;
|
||||
import com.czg.utils.PageUtil;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 挂账账单付款记录
|
||||
*
|
||||
* @author Tankaikai tankaikai@aliyun.com
|
||||
* @since 1.0 2025-03-04
|
||||
*/
|
||||
@Service
|
||||
public class CreditPaymentRecordServiceImpl extends ServiceImpl<CreditPaymentRecordMapper, CreditPaymentRecord> implements CreditPaymentRecordService {
|
||||
|
||||
private QueryWrapper buildQueryWrapper(CreditPaymentRecordQueryParam param) {
|
||||
QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
|
||||
if (StrUtil.isNotEmpty(param.getCreditBuyerId())) {
|
||||
queryWrapper.eq(CreditPaymentRecord::getCreditBuyerId, param.getCreditBuyerId());
|
||||
}
|
||||
if (ObjUtil.isNotNull(param.getOrderId())) {
|
||||
queryWrapper.eq(CreditPaymentRecord::getOrderId, param.getOrderId());
|
||||
}
|
||||
if (StrUtil.isNotEmpty(param.getPaymentMethod())) {
|
||||
queryWrapper.eq(CreditPaymentRecord::getPaymentMethod, param.getPaymentMethod());
|
||||
}
|
||||
queryWrapper.orderBy(CreditPaymentRecord::getId, false);
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<CreditPaymentRecordDTO> getCreditPaymentRecordPage(CreditPaymentRecordQueryParam param) {
|
||||
QueryWrapper queryWrapper = buildQueryWrapper(param);
|
||||
return super.pageAs(PageUtil.buildPage(), queryWrapper, CreditPaymentRecordDTO.class);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
<?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.czg.service.order.mapper.CreditBuyerMapper">
|
||||
|
||||
<sql id="view_credit_buyer_order_count">
|
||||
(SELECT
|
||||
credit_buyer_id AS credit_buyer_id,
|
||||
status AS status,
|
||||
count( 0 ) AS count
|
||||
FROM
|
||||
<include refid="view_credit_buyer_order"/>
|
||||
GROUP BY credit_buyer_id,status)
|
||||
</sql>
|
||||
|
||||
<sql id="view_credit_buyer_order">
|
||||
(SELECT t1.id AS id,
|
||||
t1.credit_buyer_id AS credit_buyer_id,
|
||||
t1.order_id AS order_id,
|
||||
t2.pay_amount - t2.refund_amount AS pay_amount,
|
||||
t1.paid_amount AS paid_amount,
|
||||
(t2.pay_amount - t2.refund_amount) - t1.paid_amount AS unpaid_amount,
|
||||
t1.status AS status,
|
||||
t2.create_time AS create_time,
|
||||
t1.last_payment_time AS last_payment_time,
|
||||
t1.last_payment_method AS last_payment_method,
|
||||
t1.remark AS remark
|
||||
FROM tb_credit_buyer_order t1
|
||||
LEFT JOIN tb_order_info t2 ON t1.order_id = t2.id)
|
||||
</sql>
|
||||
|
||||
<select id="findCreditBuyerList" resultType="com.czg.order.dto.CreditBuyerDTO">
|
||||
select x1.*,
|
||||
x2.shop_name,
|
||||
x3.owed_amount,
|
||||
x3.accumulate_amount
|
||||
from tb_credit_buyer x1
|
||||
left join tb_shop_info t2 on x1.shop_id = x2.id
|
||||
left join (select credit_buyer_id,ifnull(sum(unpaid_amount),0) as owed_amount,ifnull(sum(pay_amount),0) as
|
||||
accumulate_amount from
|
||||
<include refid="view_credit_buyer_order"/>
|
||||
group by credit_buyer_id) x3 on x1.id = x3.credit_buyer_id
|
||||
<where>
|
||||
and x1.is_del = 0
|
||||
and x1.shop_id = #{shopId}
|
||||
<if test="id !=null and id != ''">
|
||||
and x1.id = #{id}
|
||||
</if>
|
||||
<if test="responsiblePerson !=null and responsiblePerson != ''">
|
||||
and x1.responsible_person like concat('%',#{responsiblePerson},'%')
|
||||
</if>
|
||||
<if test="status !=null">
|
||||
and x1.status = #{status}
|
||||
</if>
|
||||
<if test="keywords !=null and keywords != ''">
|
||||
and (x1.debtor like concat('%',#{keywords},'%') or x1.mobile like concat('%',#{keywords},'%'))
|
||||
</if>
|
||||
<if test="repaymentStatus !=null and repaymentStatus != ''">
|
||||
<if test="repaymentStatus == 'unpaid'">
|
||||
and 0 < ifnull((select x.count from
|
||||
<include refid="view_credit_buyer_order_count"/>
|
||||
x where x.credit_buyer_id = tb_credit_buyer.id and x.status = 'unpaid'),0)
|
||||
and 0 = ifnull((select x.count from
|
||||
<include refid="view_credit_buyer_order_count"/>
|
||||
x where x.credit_buyer_id = tb_credit_buyer.id and x.status = 'partial'),0)
|
||||
</if>
|
||||
<if test="repaymentStatus == 'partial'">
|
||||
and 0 < ifnull((select x.count from
|
||||
<include refid="view_credit_buyer_order_count"/>
|
||||
x where x.credit_buyer_id = tb_credit_buyer.id and x.status = 'partial'),0)
|
||||
</if>
|
||||
<if test="repaymentStatus == 'paid'">
|
||||
and 0 = ifnull((select sum(x.count) from
|
||||
<include refid="view_credit_buyer_order_count"/>
|
||||
x where x.credit_buyer_id = tb_credit_buyer.id and x.status in ('unpaid','partial')),0)
|
||||
</if>
|
||||
</if>
|
||||
</where>
|
||||
order by x1.status desc,x1.id desc
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
<?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.czg.service.order.mapper.CreditBuyerOrderMapper">
|
||||
|
||||
<sql id="view_credit_buyer_order">
|
||||
(SELECT t1.id AS id,
|
||||
t1.credit_buyer_id AS credit_buyer_id,
|
||||
t1.order_id AS order_id,
|
||||
t2.pay_amount - t2.refund_amount AS pay_amount,
|
||||
t1.paid_amount AS paid_amount,
|
||||
(t2.pay_amount - t2.refund_amount) - t1.paid_amount AS unpaid_amount,
|
||||
t1.status AS status,
|
||||
t2.create_time AS create_time,
|
||||
t1.last_payment_time AS last_payment_time,
|
||||
t1.last_payment_method AS last_payment_method,
|
||||
t1.remark AS remark
|
||||
FROM tb_credit_buyer_order t1
|
||||
LEFT JOIN tb_order_info t2 ON t1.order_id = t2.id)
|
||||
</sql>
|
||||
|
||||
<sql id="commonWhere">
|
||||
<where>
|
||||
and x1.credit_buyer_id = #{creditBuyerId}
|
||||
<if test="orderId != null and orderId != ''">
|
||||
and x1.order_id = #{orderId}
|
||||
</if>
|
||||
<if test="beginDate != null and beginDate != ''">
|
||||
and x1.create_time >= str_to_date(concat(#{beginDate},' 00:00:00'), '%Y-%m-%d %H:%i:%s')
|
||||
</if>
|
||||
<if test="endDate != null and endDate != ''">
|
||||
<![CDATA[
|
||||
and x1.create_time <= str_to_date(concat(#{endDate},' 23:59:59'), '%Y-%m-%d %H:%i:%s')
|
||||
]]>
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
and x1.status = #{status}
|
||||
</if>
|
||||
<if test="statusList != null">
|
||||
and x1.status in
|
||||
<foreach item="status" collection="statusList" open="(" separator="," close=")">
|
||||
#{status}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="id != null">
|
||||
and x1.id = #{id}
|
||||
</if>
|
||||
</where>
|
||||
</sql>
|
||||
|
||||
<select id="findCreditBuyerOrderList" resultType="com.czg.order.dto.CreditBuyerOrderDTO">
|
||||
select * from
|
||||
<include refid="view_credit_buyer_order"/>
|
||||
x1
|
||||
<include refid="commonWhere"/>
|
||||
order by x1.order_id desc
|
||||
</select>
|
||||
<select id="getCreditBuyerOrderCount" resultType="java.lang.Long">
|
||||
select count(*) from
|
||||
<include refid="view_credit_buyer_order"/>
|
||||
x1
|
||||
<include refid="commonWhere"/>
|
||||
order by x1.order_id desc
|
||||
</select>
|
||||
<select id="getSumPayAmount" resultType="java.math.BigDecimal">
|
||||
select ifnull(sum(t1.pay_amount),0) from
|
||||
<include refid="view_credit_buyer_order"/>
|
||||
x1
|
||||
<include refid="commonWhere"/>
|
||||
order by x1.order_id desc
|
||||
</select>
|
||||
<select id="getSumPaidAmount" resultType="java.math.BigDecimal">
|
||||
select ifnull(sum(t1.paid_amount),0) from
|
||||
<include refid="view_credit_buyer_order"/>
|
||||
x1
|
||||
<include refid="commonWhere"/>
|
||||
order by x1.order_id desc
|
||||
</select>
|
||||
<select id="getSumUnpaidAmount" resultType="java.math.BigDecimal">
|
||||
select ifnull(sum(t1.unpaid_amount),0) from
|
||||
<include refid="view_credit_buyer_order"/>
|
||||
x1
|
||||
<include refid="commonWhere"/>
|
||||
order by x1.order_id desc
|
||||
</select>
|
||||
<select id="getOne" resultType="com.czg.order.dto.CreditBuyerOrderDTO">
|
||||
select * from
|
||||
<include refid="view_credit_buyer_order"/>
|
||||
x1
|
||||
<include refid="commonWhere"/>
|
||||
order by x1.order_id desc
|
||||
limit 1
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?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.czg.service.order.mapper.CreditPaymentRecordMapper">
|
||||
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue