diff --git a/cf-dependencies/pom.xml b/cf-dependencies/pom.xml index 3a92dec32..bcbc9bb72 100644 --- a/cf-dependencies/pom.xml +++ b/cf-dependencies/pom.xml @@ -78,6 +78,7 @@ 1.9.4 2.12.2 4.7.5.B + 4.7.6.B 2.5.1 @@ -608,7 +609,7 @@ com.github.binarywang weixin-java-pay - ${weixin-java.version} + ${weixin-pay-java.version} com.github.binarywang diff --git a/cf-framework/cf-spring-boot-starter-biz-pay/src/main/java/com/cf/imes/framework/pay/config/ChenfengWechatPayConfig.java b/cf-framework/cf-spring-boot-starter-biz-pay/src/main/java/com/cf/imes/framework/pay/config/ChenfengWechatPayConfig.java index 01df2fbab..90cd7062f 100644 --- a/cf-framework/cf-spring-boot-starter-biz-pay/src/main/java/com/cf/imes/framework/pay/config/ChenfengWechatPayConfig.java +++ b/cf-framework/cf-spring-boot-starter-biz-pay/src/main/java/com/cf/imes/framework/pay/config/ChenfengWechatPayConfig.java @@ -19,6 +19,11 @@ public class ChenfengWechatPayConfig extends WxPayConfig { @Value("${chenfeng.encrypt.publicKey:}") private String publicKey; + /** + * 给微信支付的回调地址 + */ + private String notifyUrl; + @Override public void setAppId(String appId) { if (StringUtils.isNotEmpty(publicKey)) { @@ -47,13 +52,56 @@ public class ChenfengWechatPayConfig extends WxPayConfig { } @Override - public void setKeyContent(byte[] keyContent) { + public void setApiV3Key(String apiV3Key) { if (StringUtils.isNotEmpty(publicKey)) { - String encrypted = new String(keyContent, StandardCharsets.UTF_8); - String decrypted = AesUtils.decrypt(encrypted, publicKey); - super.setKeyContent(decrypted.getBytes(StandardCharsets.UTF_8)); + super.setApiV3Key(AesUtils.decrypt(apiV3Key, publicKey)); } else { - super.setKeyContent(keyContent); + super.setApiV3Key(apiV3Key); + } + } + + @Override + public void setCertSerialNo(String certSerialNo) { + if (StringUtils.isNotEmpty(publicKey)) { + super.setCertSerialNo(AesUtils.decrypt(certSerialNo, publicKey)); + } else { + super.setCertSerialNo(certSerialNo); + } + } + + @Override + public void setPublicKeyId(String publicKeyId) { + if (StringUtils.isNotEmpty(publicKey)) { + super.setPublicKeyId(AesUtils.decrypt(publicKeyId, publicKey)); + } else { + super.setPublicKeyId(publicKeyId); + } + } + + @Override + public void setNotifyUrl(String notifyUrl) { + if (StringUtils.isNotEmpty(publicKey)) { + super.setNotifyUrl(AesUtils.decrypt(notifyUrl, publicKey)); + } else { + super.setNotifyUrl(notifyUrl); + } + } + + @Override + public void setPublicKeyString(String publicKeyString) { + if (StringUtils.isNotEmpty(publicKey)) { + super.setPublicKeyContent(AesUtils.decrypt(publicKeyString, publicKey).getBytes(StandardCharsets.UTF_8)); + } else { + super.setPublicKeyContent(publicKeyString.getBytes(StandardCharsets.UTF_8)); + } + } + + @Override + public void setPrivateKeyString(String privateKeyString) { + if (StringUtils.isNotEmpty(publicKey)) { + super.setPrivateKeyContent(AesUtils.decrypt(privateKeyString, publicKey).getBytes(StandardCharsets.UTF_8)); + } else { + super.setPrivateKeyContent(privateKeyString.getBytes(StandardCharsets.UTF_8)); } } } diff --git a/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/enums/ErrorCodeConstants.java b/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/enums/ErrorCodeConstants.java index 78efd8ff1..99b72d520 100644 --- a/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/enums/ErrorCodeConstants.java +++ b/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/enums/ErrorCodeConstants.java @@ -437,6 +437,7 @@ public class ErrorCodeConstants { public static final ErrorCode ORGAN_PRODUCT_PAY_AMOUNT_CHANGE_ERROR = new ErrorCode(1_002_043_025, "发起产品支付失败,组织资金已发生改变,请刷新或稍后再发起支付"); public static final ErrorCode PAY_RECHARGE_ACTIVITY_CHANNEL_MISMATCH_ERROR = new ErrorCode(1_002_043_026, "充值活动类型和支付渠道不匹配,请选择其他充值活动!"); public static final ErrorCode PAY_RECHARGE_ACTIVITY_EXPIRE_ERROR = new ErrorCode(1_002_043_027, "充值活动已结束,请选择其他充值活动!"); + public static final ErrorCode INVOICE_TITLE_NOT_EXISTS_ERROR = new ErrorCode(1_002_043_028, "发票抬头不存在,请先创建发票抬头"); //=========== 支付相关 1-002-048-000 ============ public static final ErrorCode PAY_CHANNEL_NOT_SUPPORT = new ErrorCode(1_002_048_000, "暂不支持的支付渠道,请使用其他支付渠道"); diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/InvoiceController.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/InvoiceController.java index 12ab5129c..f8bdbaecd 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/InvoiceController.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/InvoiceController.java @@ -2,11 +2,14 @@ package com.cf.imes.module.system.controller.admin.funds.invoice; import com.cf.imes.framework.common.pojo.CommonResult; +import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceAmountAndAvailablePageReqVO; +import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceAmountAndAvailablePageRespVO; import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceTitleReqVO; import com.cf.imes.module.system.service.funds.invoice.InvoiceService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -32,15 +35,16 @@ public class InvoiceController { private InvoiceService invoiceService; - @PostMapping("") + @PostMapping("/title") @Operation(summary = "新增/修改发票抬头信息") public CommonResult insetInvoiceTitle(@Valid @RequestBody InvoiceTitleReqVO reqVO) { - invoiceService.insetInvoiceTitle(reqVO); - return success(Boolean.TRUE); - } - + @GetMapping("/available/info") + @Operation(summary = "获取组织的开票金额信息") + public CommonResult getInvoiceAmountAndAvailablePage(@Valid InvoiceAmountAndAvailablePageReqVO pageReqVO) { + return success(invoiceService.getInvoiceAmount(pageReqVO)); + } } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceAmountAndAvailablePageReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceAmountAndAvailablePageReqVO.java new file mode 100644 index 000000000..4f6e3efb4 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceAmountAndAvailablePageReqVO.java @@ -0,0 +1,29 @@ +package com.cf.imes.module.system.controller.admin.funds.invoice.vo; + +import com.cf.imes.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** + * @author Gqr + * @since 2025/8/21 16:11 + */ +@Data +@Schema(description = "管理后台 - 组织开票金额和可开票列表 Req VO") +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class InvoiceAmountAndAvailablePageReqVO extends PageParam { + @Schema(description = "费用账期", example = "[2022-07-01 01:01:01 ,2022-07-01 01:01:01]") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + + @Schema(description = "开票金额", example = "[0,100]") + private Integer[] invoiceAmount; +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceAmountAndAvailablePageRespVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceAmountAndAvailablePageRespVO.java new file mode 100644 index 000000000..acf0a710a --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceAmountAndAvailablePageRespVO.java @@ -0,0 +1,20 @@ +package com.cf.imes.module.system.controller.admin.funds.invoice.vo; + +import com.cf.imes.framework.common.pojo.PageResult; +import com.cf.imes.module.system.dal.dataobject.funds.purchase.PurchaseRecordDO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * @author Gqr + * @since 2025/8/21 16:11 + */ +@Data +@Schema(description = "管理后台 - 组织开票金额和可开票列表 Response VO") +public class InvoiceAmountAndAvailablePageRespVO { + @Schema(description = "发票金额信息") + private InvoiceAmountRespVO invoiceAmountRespVO; + + @Schema(description = "可开票记录") + private PageResult availableInvoicePurchaseRecords; +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceAmountRespVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceAmountRespVO.java new file mode 100644 index 000000000..856689072 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceAmountRespVO.java @@ -0,0 +1,23 @@ +package com.cf.imes.module.system.controller.admin.funds.invoice.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class InvoiceAmountRespVO { + + + @Schema(description = "可开票") + private BigDecimal invocable; + + + @Schema(description = "开票中") + private BigDecimal inTheInvoice; + + + @Schema(description = "已开票") + private BigDecimal invoiced; + +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceDetailsPageReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceDetailsPageReqVO.java new file mode 100644 index 000000000..3f368e5c9 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceDetailsPageReqVO.java @@ -0,0 +1,61 @@ +package com.cf.imes.module.system.controller.admin.funds.invoice.vo; + + +import com.cf.imes.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 组织可开票的数据明细 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@Builder +public class InvoiceDetailsPageReqVO extends PageParam { + + + @Schema(description = "组织ID") + private Long organId; + + + @Schema(description = "发票号") + private String invoiceNo; + + + @Schema(description = "发票状态,1待开票 2已开票 3开票失败") + private Integer status; + + + @Schema(description = "申请人") + private String creator; + + + @Schema(description = "开票人") + private String invoicePerson; + + + @Schema(description = "发票金额") + private BigDecimal[] invoiceAmount; + + + @Schema(description = "开票时间", example = "[2022-07-01 01:01:01 ,2022-07-01 01:01:01]") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] invoiceTime; + + + @Schema(description = "交易时间", example = "[2022-07-01 01:01:01 ,2022-07-01 01:01:01]") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + + + @Schema(description = "交易金额") + private BigDecimal[] amount; + + +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceDetailsRespVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceDetailsRespVO.java new file mode 100644 index 000000000..9a34be0e1 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceDetailsRespVO.java @@ -0,0 +1,28 @@ +package com.cf.imes.module.system.controller.admin.funds.invoice.vo; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class InvoiceDetailsRespVO { + + + @Schema(description = "发票对应的购买记录") + private List invoicePurchaseRecords; + + + @Schema(description = "发票抬头信息") + private InvoiceTitleInfo invoiceTitleInfo; + + +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoicePurchaseRecord.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoicePurchaseRecord.java new file mode 100644 index 000000000..1ac449833 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoicePurchaseRecord.java @@ -0,0 +1,38 @@ +package com.cf.imes.module.system.controller.admin.funds.invoice.vo; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + + +@Data +public class InvoicePurchaseRecord { + + + @Schema(description = "流水号") + private Long businessNo; + + + @Schema(description = "购买记录ID") + private Long purchaseRecordId; + + + @Schema(description = "产品名称") + private String productName; + + + @Schema(description = "交易类型") + private Integer tradeType; + + + @Schema(description = "可开票金额") + private BigDecimal rechargeAmount; + + + @Schema(description = "交易时间") + private LocalDateTime createTime; + +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceTitleInfo.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceTitleInfo.java new file mode 100644 index 000000000..f3f9bf3fa --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceTitleInfo.java @@ -0,0 +1,55 @@ +package com.cf.imes.module.system.controller.admin.funds.invoice.vo; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class InvoiceTitleInfo { + + + @Schema(description = "发票抬头ID") + private Long id; + + + @Schema(description = "组织ID") + private Long organId; + + + @Schema(description = "发票抬头") + private String invoiceTitle; + + + @Schema(description = "开具类型,0企业 1个人") + private Integer issueType; + + + @Schema(description = "发票类型,0增值税普通发票 1增值税专用发票") + private Integer invoiceType; + + + @Schema(description = "纳税人识别号") + private String taxpayerId; + + + @Schema(description = "开户银行名称") + private String bankName; + + + @Schema(description = "开户银行账号") + private String bankAccount; + + + @Schema(description = "注册场所地址") + private String registeredAddress; + + + @Schema(description = "注册固定电话") + private String fixedPhone; + + + @Schema(description = "邮箱") + private String email; + + +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceTitleReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceTitleReqVO.java index ec5424ea4..75dd93718 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceTitleReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/invoice/vo/InvoiceTitleReqVO.java @@ -1,7 +1,11 @@ package com.cf.imes.module.system.controller.admin.funds.invoice.vo; +import com.cf.imes.module.system.validation.invoice.InvoiceIssueTypeValid; +import com.cf.imes.module.system.validation.invoice.InvoiceTypeValid; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Size; import lombok.Data; import jakarta.validation.constraints.NotBlank; @@ -16,47 +20,58 @@ public class InvoiceTitleReqVO { @Schema(description = "组织ID") + @NotNull(message = "组织ID不能为空") private Long organId; @Schema(description = "发票抬头") @NotBlank(message = "发票抬头不能为空") + @Size(max = 64, message = "发票抬头长度不能超过64个字符") private String invoiceTitle; @Schema(description = "开具类型,0企业 1个人") @NotNull(message = "开具类型不能为空") + @InvoiceIssueTypeValid private Integer issueType; @Schema(description = "发票类型,0增值税普通发票 1增值税专用发票") @NotNull(message = "发票类型不能为空") + @InvoiceTypeValid private Integer invoiceType; @Schema(description = "纳税人识别号") @NotNull(message = "纳税人识别号不能为空") + @Size(max = 20, message = "纳税人识别号长度不能超过20个字符") private String taxpayerId; @Schema(description = "开户银行名称") + @Size(max = 64, message = "开户银行名称长度不能超过64个字符") private String bankName; @Schema(description = "开户银行账号") + @Size(max = 40, message = "开户银行账号长度不能超过40个字符") private String bankAccount; @Schema(description = "注册场所地址") + @Size(max = 64, message = "注册场所地址长度不能超过64个字符") private String registeredAddress; @Schema(description = "注册固定电话") + @Size(max = 20, message = "注册固定电话长度不能超过20个字符") private String fixedPhone; @Schema(description = "邮箱") @NotNull(message = "邮箱不能为空") + @Size(max = 64, message = "邮箱长度不能超过64个字符") + @Email(message = "邮箱格式不正确") private String email; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/PayController.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/PayController.java index a6eeba716..0d88990fb 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/PayController.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/PayController.java @@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -67,9 +68,10 @@ public class PayController { @PermitAll public String notifyOrder(@PathVariable("channelCode") Integer channelCode, @RequestParam(required = false) Map params, - @RequestBody(required = false) String body) { - log.info("[notifyOrder][channelCode({}) 回调数据({}/{})]", channelCode, params, body); - payOrderService.doOrderNotify(channelCode, params, body); + @RequestBody(required = false) String body, + @RequestHeader Map headers) { + log.info("[notifyOrder][channelCode({}) 回调数据({}/{}/{})]", channelCode, params, body, headers); + payOrderService.doOrderNotify(channelCode, params, body, headers); // 支付接口回调相应必须是"success" return "success"; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/funds/purchase/PurchaseRecordMapper.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/funds/purchase/PurchaseRecordMapper.java index cfb5e770f..7cd1488b9 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/funds/purchase/PurchaseRecordMapper.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/funds/purchase/PurchaseRecordMapper.java @@ -1,10 +1,15 @@ package com.cf.imes.module.system.dal.mysql.funds.purchase; +import cn.hutool.core.util.ObjectUtil; import com.cf.imes.framework.common.pojo.PageResult; import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX; import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX; +import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils; +import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceAmountAndAvailablePageReqVO; +import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceAmountRespVO; import com.cf.imes.module.system.controller.admin.funds.purchase.vo.PurchaseRecordPageReqVO; import com.cf.imes.module.system.dal.dataobject.funds.purchase.PurchaseRecordDO; +import com.cf.imes.module.system.enums.pay.InvoiceStatusEnum; import org.apache.ibatis.annotations.Mapper; import java.math.BigDecimal; @@ -38,4 +43,29 @@ public interface PurchaseRecordMapper extends BaseMapperX { .likeIfPresent(PurchaseRecordDO::getCreator, pageReqVO.getCreator())); } + + /** + * 分页查询可开票记录 + * + * @param pageReqVO + * @return + */ + default PageResult selectPage(InvoiceAmountAndAvailablePageReqVO pageReqVO) { + return selectPage(pageReqVO, new LambdaQueryWrapperX() + .betweenIfPresent(PurchaseRecordDO::getCreateTime, pageReqVO.getCreateTime()) + .geIfPresent(PurchaseRecordDO::getTotalAmount, ObjectUtil.isNotNull(pageReqVO.getInvoiceAmount()) ? pageReqVO.getInvoiceAmount()[0] : null) + .leIfPresent(PurchaseRecordDO::getTotalAmount, ObjectUtil.isNotNull(pageReqVO.getInvoiceAmount()) ? pageReqVO.getInvoiceAmount()[1] : null) + .eq(PurchaseRecordDO::getOrganId, SecurityFrameworkUtils.getUserOrganId()) + .eq(PurchaseRecordDO::getDeleted, false) + .in(PurchaseRecordDO::getIsInvocing, InvoiceStatusEnum.INVOICABLE.getStatus(), InvoiceStatusEnum.INVOICINGFAILED.getStatus()) + ); + + } + + /** + * 查询机构下开票金额统计:可开票、开票中、已开票 + * @param organId + * @return + */ + InvoiceAmountRespVO getOrgInvoiceAmountStatistics(Long organId); } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/InvoiceIssueTypeEnum.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/InvoiceIssueTypeEnum.java new file mode 100644 index 000000000..ac1aaf036 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/InvoiceIssueTypeEnum.java @@ -0,0 +1,25 @@ +package com.cf.imes.module.system.enums.pay; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 发票开具类型枚举 + * @author Gqr + * @since 2025/8/21 12:00 + */ +@Getter +@AllArgsConstructor +public enum InvoiceIssueTypeEnum { + /** + * 企业 + */ + ENTERPRISE(0), + + /** + * 个人 + */ + PERSONAL(1); + + private final Integer value; +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/InvoiceTypeEnum.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/InvoiceTypeEnum.java new file mode 100644 index 000000000..976a28886 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/InvoiceTypeEnum.java @@ -0,0 +1,28 @@ +package com.cf.imes.module.system.enums.pay; + +/** + * 发票类型枚举 + * @author Gqr + * @since 2025/8/21 12:03 + */ +public enum InvoiceTypeEnum { + /** + * 增值税普通发票 + */ + VAT_GENERAL(0), + + /** + * 增值税专用发票 + */ + VAT_SPECIAL(1); + + private final Integer value; + + InvoiceTypeEnum(Integer value) { + this.value = value; + } + + public Integer getValue() { + return value; + } +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/PayConstants.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/PayConstants.java index 7aadead3b..00659f363 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/PayConstants.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/PayConstants.java @@ -11,7 +11,7 @@ public class PayConstants { public static final String PAY_PASSBACK_PARAMS_KEY = "passback_params";// 回调参数passback key - public static final String PAY_ORDER_PREFIX_FORMAT = "P%dO%s%s"; + public static final String PAY_ORDER_PREFIX_FORMAT = "P%dO%s"; public static final String PAY_PASSBACK_PARAMS_PURCHASE_RECORD_ID_KEY = "purchaseRecordId"; //支付passback 购买记录key } \ No newline at end of file diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/invoice/InvoiceService.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/invoice/InvoiceService.java index 839b5a0b1..e6ceb8067 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/invoice/InvoiceService.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/invoice/InvoiceService.java @@ -1,6 +1,11 @@ package com.cf.imes.module.system.service.funds.invoice; +import com.cf.imes.framework.common.pojo.PageResult; +import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceAmountAndAvailablePageReqVO; +import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceAmountAndAvailablePageRespVO; +import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceDetailsPageReqVO; +import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceDetailsRespVO; import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceTitleReqVO; /** @@ -8,5 +13,26 @@ import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceTitleR */ public interface InvoiceService { + /** + * 新增/修改抬头信息 + * + * @param reqVO + */ void insetInvoiceTitle(InvoiceTitleReqVO reqVO); + + /** + * 查询组织开票金额和可开票列表 + * + * @param invoiceAmountAndAvailablePageReqVO + * @return + */ + InvoiceAmountAndAvailablePageRespVO getInvoiceAmount(InvoiceAmountAndAvailablePageReqVO invoiceAmountAndAvailablePageReqVO); + + /** + * 查询开票分页 + * + * @param pageReqVO + * @return + */ + PageResult getInvoiceDetails(InvoiceDetailsPageReqVO pageReqVO); } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/invoice/InvoiceServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/invoice/InvoiceServiceImpl.java index 89fbddc2a..b954af8b8 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/invoice/InvoiceServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/invoice/InvoiceServiceImpl.java @@ -1,40 +1,55 @@ package com.cf.imes.module.system.service.funds.invoice; +import com.cf.imes.framework.common.pojo.PageResult; +import com.cf.imes.framework.common.util.Assert.AssertUtils; import com.cf.imes.framework.common.util.object.BeanUtils; +import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils; +import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceAmountAndAvailablePageReqVO; +import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceAmountAndAvailablePageRespVO; +import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceDetailsPageReqVO; +import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceDetailsRespVO; import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceTitleReqVO; import com.cf.imes.module.system.dal.dataobject.funds.invoice.InvoiceTitleInfoDO; import com.cf.imes.module.system.dal.mysql.funds.invoice.InvoiceTitleInfoMapper; +import com.cf.imes.module.system.dal.mysql.funds.purchase.PurchaseRecordMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import jakarta.annotation.Resource; +import static com.cf.imes.module.system.enums.ErrorCodeConstants.INVOICE_TITLE_NOT_EXISTS_ERROR; + /** * @author 发票管理接口 实现类 */ @Slf4j @Service -public class InvoiceServiceImpl implements InvoiceService{ +public class InvoiceServiceImpl implements InvoiceService { @Resource private InvoiceTitleInfoMapper invoiceTitleInfoMapper; + @Resource + private PurchaseRecordMapper purchaseRecordMapper; + @Override public void insetInvoiceTitle(InvoiceTitleReqVO reqVO) { - - if(reqVO.getId() != null){ + if (reqVO.getId() != null) { + validTitleOrg(reqVO.getId(), reqVO.getOrganId()); + // 更新抬头 InvoiceTitleInfoDO titleInfoDO = BeanUtils.toBean(reqVO, InvoiceTitleInfoDO.class); invoiceTitleInfoMapper.updateById(titleInfoDO); return; } - + // 新增抬头 invoiceTitleInfoMapper.insert(InvoiceTitleInfoDO.builder() + .organId(reqVO.getOrganId()) .invoiceTitle(reqVO.getInvoiceTitle()) .invoiceType(reqVO.getInvoiceType()) .issueType(reqVO.getIssueType()) @@ -45,6 +60,63 @@ public class InvoiceServiceImpl implements InvoiceService{ .fixedPhone(reqVO.getFixedPhone()) .email(reqVO.getEmail()) .build()); + } + + /** + * 校验抬头组织 + * + * @param id + * @param organId + */ + private void validTitleOrg(Long id, Long organId) { + InvoiceTitleInfoDO titleInfoDO = invoiceTitleInfoMapper.selectById(id); + // 抬头不存在 + AssertUtils.notEmpty(titleInfoDO, INVOICE_TITLE_NOT_EXISTS_ERROR); + // 抬头组织不匹配 + AssertUtils.notEquals(titleInfoDO.getOrganId(), organId, INVOICE_TITLE_NOT_EXISTS_ERROR); + } + + @Override + public InvoiceAmountAndAvailablePageRespVO getInvoiceAmount(InvoiceAmountAndAvailablePageReqVO invoiceAmountAndAvailablePageReqVO) { + InvoiceAmountAndAvailablePageRespVO invoiceAmountAndAvailablePageRespVO = new InvoiceAmountAndAvailablePageRespVO(); + // 开票金额 + invoiceAmountAndAvailablePageRespVO.setInvoiceAmountRespVO(purchaseRecordMapper.getOrgInvoiceAmountStatistics(SecurityFrameworkUtils.getUserOrganId())); + + // 可开票记录查询 + invoiceAmountAndAvailablePageRespVO.setAvailableInvoicePurchaseRecords(purchaseRecordMapper.selectPage(invoiceAmountAndAvailablePageReqVO)); + + return invoiceAmountAndAvailablePageRespVO; + } + + @Override + public PageResult getInvoiceDetails(InvoiceDetailsPageReqVO pageReqVO) { +// +// PageDTO page = new PageDTO<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()); +// +// List invoiceStatus = new ArrayList<>(); +// invoiceStatus.add(InvoiceStatusEnum.INVOICABLE.getStatus()); +// invoiceStatus.add(InvoiceStatusEnum.INVOICINGFAILED.getStatus()); +// +// QueryWrapperX queryWrapperX = new QueryWrapperX<>(); +// +// pageReqVO.setCreateTime(LocalDateTimeUtils.generateTimeSection(pageReqVO.getCreateTime())); +// queryWrapperX +// .eq("ied.organId",getUserOrganId()) +// .eq("ied.deleted",false) +// .eq("ied.trade_type", TradeTypeEnum.PRODUCT.getCode()) +// .in("pr.is_invocing", invoiceStatus) +// .betweenIfPresent("ied.create_time",pageReqVO.getCreateTime()) +// .betweenIfPresent("ied.cash_amount_change",pageReqVO.getAmount()); +// +// IPage respVOIPage = incomeExpenseDetailsMapper.selectOrganInvoicable(page, queryWrapperX); +// +// List records = respVOIPage.getRecords(); +// if (CollUtil.isEmpty(records)) { +// return new PageResult<>(); +// } +// +// return new PageResult<>(records, respVOIPage.getTotal()); + return null; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderService.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderService.java index 166e821ac..68840fefa 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderService.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderService.java @@ -43,7 +43,7 @@ public interface PayOrderService { * @param body * @return */ - void doOrderNotify(Integer channelCode, Map params, String body); + void doOrderNotify(Integer channelCode, Map params, String body, Map headers); /** * 处理过期订单 diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderServiceImpl.java index a1144c497..a1c40b82e 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderServiceImpl.java @@ -1,7 +1,5 @@ package com.cf.imes.module.system.service.pay; -import cn.hutool.core.date.DatePattern; -import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; @@ -320,7 +318,7 @@ public class PayOrderServiceImpl implements PayOrderService { Long organId = SecurityFrameworkUtils.getUserOrganId(); payOrderDO.setId(payOrderId); - payOrderDO.setPayNo(String.format(PayConstants.PAY_ORDER_PREFIX_FORMAT, organId, payOrderId, DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN))); + payOrderDO.setPayNo(String.format(PayConstants.PAY_ORDER_PREFIX_FORMAT, organId, payOrderId)); payOrderDO.setStatus(PayOrderStatusEnum.WAITING); payOrderDO.setExpireTime(LocalDateTime.now().plus(payConfig.getPayExpireTime())); payOrderDO.setPrice(price); @@ -385,18 +383,18 @@ public class PayOrderServiceImpl implements PayOrderService { @Override @Transactional(rollbackFor = Exception.class) - public void doOrderNotify(Integer channelCode, Map params, String body) { + public void doOrderNotify(Integer channelCode, Map params, String body, Map headers) { // 获取渠道方处理器 AbstractPayHandler payHandler = payHandlerFactory.getPayHandler(channelCode); try { // 解析回调数据 - PayOrderRespDTO payOrderRespDTO = payHandler.doParseOrderNotify(params, body); + PayOrderRespDTO payOrderRespDTO = payHandler.doParseOrderNotify(params, body, headers); // 处理支付回调数据 this.notifyOrder(payOrderRespDTO); } catch (Throwable e) { - log.error("[parseOrderNotify][客户端({}) params({}) body({}) headers({}) 解析失败]", channelCode, params, body, e); + log.error("[parseOrderNotify][客户端({}) params({}) body({}) headers({}) 解析失败]", channelCode, params, body, headers, e); throw new PayException(PAY_ORDER_NOTIFY_DATA_PARSE_ERROR); } } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/AbstractPayHandler.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/AbstractPayHandler.java index 6eb3c0d53..499ad77a9 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/AbstractPayHandler.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/AbstractPayHandler.java @@ -36,5 +36,5 @@ public abstract class AbstractPayHandler { * @param body * @return */ - public abstract PayOrderRespDTO doParseOrderNotify(Map params, String body) throws Throwable; + public abstract PayOrderRespDTO doParseOrderNotify(Map params, String body, Map headers) throws Throwable; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/alipay/AlipayPcPayHandler.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/alipay/AlipayPcPayHandler.java index 04b8f4eaa..6de1fa781 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/alipay/AlipayPcPayHandler.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/alipay/AlipayPcPayHandler.java @@ -108,7 +108,7 @@ public class AlipayPcPayHandler extends AbstractPayHandler { } @Override - public PayOrderRespDTO doParseOrderNotify(Map params, String body) throws Throwable { + public PayOrderRespDTO doParseOrderNotify(Map params, String body, Map headers) throws Throwable { // 1. 校验回调数据 verifyNotifyData(params); diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/wechat/WechatNativePayHandler.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/wechat/WechatNativePayHandler.java index f0ea7f8ba..037913d74 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/wechat/WechatNativePayHandler.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/wechat/WechatNativePayHandler.java @@ -2,6 +2,7 @@ package com.cf.imes.module.system.service.pay.factory.impl.wechat; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.date.TemporalAccessorUtil; +import cn.hutool.core.text.CharSequenceUtil; import com.alibaba.fastjson.JSON; import com.cf.imes.framework.common.util.json.JsonUtils; import com.cf.imes.framework.pay.config.ChenfengWechatPayConfig; @@ -10,9 +11,10 @@ import com.cf.imes.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import com.cf.imes.framework.pay.core.enums.order.PayOrderDisplayModeEnum; import com.cf.imes.module.system.enums.pay.PayOrderStatusEnum; import com.cf.imes.module.system.service.pay.factory.impl.AbstractPayHandler; -import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; -import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult; -import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; +import com.github.binarywang.wxpay.bean.notify.SignatureHeader; +import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result; +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request; +import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; @@ -23,9 +25,9 @@ import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Map; -import java.util.Objects; -import static cn.hutool.core.date.DatePattern.PURE_DATETIME_PATTERN; +import static cn.hutool.core.date.DatePattern.UTC_WITH_XXX_OFFSET_PATTERN; +import static com.cf.imes.framework.common.util.servlet.ServletUtils.getClientIP; /** * 微信native支付处理器 @@ -43,22 +45,21 @@ public class WechatNativePayHandler extends AbstractPayHandler { @Override public PayOrderRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { // 构建 WxPayUnifiedOrderRequest 对象 - WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder() - .outTradeNo(reqDTO.getOutTradeNo()) - .body(reqDTO.getSubject()) - .detail(reqDTO.getBody()) - .totalFee(reqDTO.getPrice()) // 单位分 - .timeExpire(TemporalAccessorUtil.format(reqDTO.getExpireTime().atZone(ZoneId.systemDefault()), PURE_DATETIME_PATTERN)) - .spbillCreateIp(reqDTO.getUserIp()) - .notifyUrl(reqDTO.getNotifyUrl()) - .attach(JSON.toJSONString(reqDTO.getPassbackParams())) - .build(); + WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request(); + request.setOutTradeNo(reqDTO.getOutTradeNo()); + request.setDescription(reqDTO.getSubject()); + request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getPrice())); // 单位分 + request.setTimeExpire(formatDateV3(reqDTO.getExpireTime())); + request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(getClientIP())); + request.setNotifyUrl(reqDTO.getNotifyUrl()); + request.setAttach(JSON.toJSONString(reqDTO.getPassbackParams())); + // 加载配置,创建client WxPayService client = new WxPayServiceImpl(); client.setConfig(chenfengWechatPayConfig); // 执行请求 - WxPayAppOrderResult response = client.createOrder(request); + String response = client.createOrderV3(TradeTypeEnum.NATIVE, request); // 转换结果 return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), JsonUtils.toJsonString(response), @@ -71,20 +72,60 @@ public class WechatNativePayHandler extends AbstractPayHandler { } @Override - public PayOrderRespDTO doParseOrderNotify(Map params, String body) throws WxPayException { + public PayOrderRespDTO doParseOrderNotify(Map params, String body, Map headers) throws WxPayException { // 1. 解析回调 + SignatureHeader signatureHeader = getRequestHeader(headers); + // 加载配置,创建client WxPayService client = new WxPayServiceImpl(); client.setConfig(chenfengWechatPayConfig); - WxPayOrderNotifyResult response = client.parseOrderNotifyResult(body); + + WxPayNotifyV3Result response = client.parseOrderNotifyV3Result(body, signatureHeader); + WxPayNotifyV3Result.DecryptNotifyResult result = response.getResult(); // 2. 构建结果 - // V2 微信支付的回调,只有 SUCCESS 支付成功、CLOSED 支付失败两种情况,无需像支付宝一样解析的比较复杂 - Integer status = Objects.equals(response.getResultCode(), "SUCCESS") ? - PayOrderStatusEnum.SUCCESS.getStatus() : PayOrderStatusEnum.FAIL.getStatus(); - return PayOrderRespDTO.of(status, response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()), - response.getOutTradeNo(), body); + Integer status = parseStatus(result.getTradeState()); + String openid = result.getPayer() != null ? result.getPayer().getOpenid() : null; + return PayOrderRespDTO.of(status, result.getTransactionId(), openid, parseDateV3(result.getSuccessTime()), + result.getOutTradeNo(), body); } - static LocalDateTime parseDateV2(String time) { - return LocalDateTimeUtil.parse(time, PURE_DATETIME_PATTERN); + static String formatDateV3(LocalDateTime time) { + return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), UTC_WITH_XXX_OFFSET_PATTERN); } + + /** + * 组装请求头重的签名信息 + * + * @see 官方示例 + */ + private SignatureHeader getRequestHeader(Map headers) { + return SignatureHeader.builder() + .signature(headers.get("wechatpay-signature")) + .nonce(headers.get("wechatpay-nonce")) + .serial(headers.get("wechatpay-serial")) + .timeStamp(headers.get("wechatpay-timestamp")) + .build(); + } + + private static Integer parseStatus(String tradeState) { + switch (tradeState) { + case "NOTPAY": + case "USERPAYING": // 支付中,等待用户输入密码(条码支付独有) + return PayOrderStatusEnum.WAITING.getStatus(); + case "SUCCESS": + return PayOrderStatusEnum.SUCCESS.getStatus(); +// case "REFUND": +// return PayOrderStatusEnum.REFUND.getStatus(); + case "CLOSED": + case "REVOKED": // 已撤销(刷卡支付独有) + case "PAYERROR": // 支付失败(其它原因,如银行返回失败) + return PayOrderStatusEnum.FAIL.getStatus(); + default: + throw new IllegalArgumentException(CharSequenceUtil.format("未知的支付状态({})", tradeState)); + } + } + + static LocalDateTime parseDateV3(String time) { + return LocalDateTimeUtil.parse(time, UTC_WITH_XXX_OFFSET_PATTERN); + } + } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceIssueTypeValid.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceIssueTypeValid.java new file mode 100644 index 000000000..13bf962a3 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceIssueTypeValid.java @@ -0,0 +1,32 @@ +package com.cf.imes.module.system.validation.invoice; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 发票开具类型校验注解 + * + * @author Gqr + * @since 2025/8/21 14:36 + */ +@Target({ + ElementType.FIELD, +}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint( + validatedBy = {InvoiceIssueTypeValidtor.class} +) +public @interface InvoiceIssueTypeValid { + String message() default "不支持的发票开具类型"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceIssueTypeValidtor.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceIssueTypeValidtor.java new file mode 100644 index 000000000..545a66833 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceIssueTypeValidtor.java @@ -0,0 +1,27 @@ +package com.cf.imes.module.system.validation.invoice; + +import cn.hutool.core.util.ObjectUtil; +import com.cf.imes.module.system.enums.pay.InvoiceIssueTypeEnum; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +/** + * 发票开具类型校验器 + * + * @author Gqr + * @since 2025/8/21 14:37 + */ +public class InvoiceIssueTypeValidtor implements ConstraintValidator { + @Override + public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) { + if (ObjectUtil.isNull(integer)) { + return true; + } + for (InvoiceIssueTypeEnum issueTypeEnum : InvoiceIssueTypeEnum.values()) { + if (issueTypeEnum.getValue().equals(integer)) { + return true; + } + } + return false; + } +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceTypeValid.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceTypeValid.java new file mode 100644 index 000000000..a77c4117b --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceTypeValid.java @@ -0,0 +1,32 @@ +package com.cf.imes.module.system.validation.invoice; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 发票类型校验注解 + * + * @author Gqr + * @since 2025/8/21 14:36 + */ +@Target({ + ElementType.FIELD, +}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint( + validatedBy = {InvoiceTypeValidtor.class} +) +public @interface InvoiceTypeValid { + String message() default "不支持的发票类型"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceTypeValidtor.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceTypeValidtor.java new file mode 100644 index 000000000..72eedcbc8 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/invoice/InvoiceTypeValidtor.java @@ -0,0 +1,27 @@ +package com.cf.imes.module.system.validation.invoice; + +import cn.hutool.core.util.ObjectUtil; +import com.cf.imes.module.system.enums.pay.InvoiceTypeEnum; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +/** + * 发票类型校验器 + * + * @author Gqr + * @since 2025/8/21 14:37 + */ +public class InvoiceTypeValidtor implements ConstraintValidator { + @Override + public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) { + if (ObjectUtil.isNull(integer)) { + return true; + } + for (InvoiceTypeEnum invoiceTypeEnum : InvoiceTypeEnum.values()) { + if (invoiceTypeEnum.getValue().equals(integer)) { + return true; + } + } + return false; + } +} diff --git a/cf-module-system/cf-module-system-biz/src/main/resources/application-dev.yaml b/cf-module-system/cf-module-system-biz/src/main/resources/application-dev.yaml index 0b3c60744..7e15ddb7b 100644 --- a/cf-module-system/cf-module-system-biz/src/main/resources/application-dev.yaml +++ b/cf-module-system/cf-module-system-biz/src/main/resources/application-dev.yaml @@ -266,6 +266,17 @@ chenfeng: privateKey: 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 alipayPublicKey: KbUGE7zsPBKWPx0/zMcAdLRldKrcgy2LRiOrqOBm7y4iPJLXTYtXFJT15p2JMQiyOM8mqiYQR0OEDwfrKxDgHXLtIut/e0EAk9bZwZoLrqVe0pN1huseRC38zEglbWil3yz+tZfHZuAaEq2EzvWJltX/tRKOzNBqAT9l+UvnqNedgCFB9MY2EErqJjbn/at3gYCkV2idt31ghF0z8SEQ5h9ztNYtmTvk8c8ipi0/hIjX8XryN6mlOvGQfyZ4rWrBWBuZ6iD/SyuThwxKmFYU4dhHbHVpBrva5nJWU43CP7RVaJm649nNJnce+Ppj2Tv8+ugSLe5poZWo2zmGe3Xn5WmN6OTZyRI1pnmn2/hGxtOMmTZJX7Gh0pI4v3wmU0gOd/gbRlqlvN+u12T92nyH8MQrHdA7UXuttAtolYUa/Rli/20qHX69QtOtvfZk8mNvDSj9dDvODseGcrFHm07jyfxpaIkQDeN75cQ3NwNgDQEW8urQszaU1IJ7hc+20tt0Z3td4+7MfiVPpGfVxsGE66gwLgpB8wsxEhyBTaBr7osMLqOv notifyUrl: VvJ5DOVuGOBw39j7tyrvsEEtLSseVM8T3u9kqsWKago+iI5ao8JzoggmeSe+N9LrsYxutK4fkGpmr4jOGJ3JTQFZ7YBXLxf2oLIXOZH9O27EnDtm + wechat: + appId: vTVnNGeOPD8AeiTIS5cnUzq8q3EiOW0HZ18QtxFE/UxTYwV1DSwxrbYDbBGjoA== + mchId: p/zqgyb9tAG9n9DKROHdHuIv0FNQGfbQ0AH7uTsglakv9J4ZHGA= + mchKey: tdnmIOPmmqq0ST47xYWg61chgI2ycJGhjeApSjnraW103upgR/EMx/qfbFMVKA59BISqzbSukjQPV5pR + apiV3Key: tdnmIOPmmqq0ST47xYWg61chgI2ycJGhjeApSjnraW103upgR/EMx/qfbFMVKA59BISqzbSukjQPV5pR + publicKeyId: 9NU9NFR9WWUaN2xfCujfPhcOToJop6M0G4JGbpZDlkrfCQVK3KYDOEeinJwEuxvJGcoO2hKUVkapHmeUngH3VxPu+qBcf+gN8Q== + certSerialNo: zzAFIJnTSEhme+K37z/ciNI04S//eHxBR/VCKLdGRGTrWAlvHYU2LSw9YPl07OEBGOpIBHG3oep77cr5g8wpGXGRvJQ= + tradeType: eaQet/V56gw8fTCVKypLG8cAjgheMpxKo6Y6wQab1P5b9w== + publicKeyString: F+bPjhy/AwNvl16dMdqHCgKYIfA9c8Tho+g+fAeNOb7GjQf0NCX36B2ZH7yngpN6v82Q10/PfblVrPGrvMbDZcU4gxomhXN22L2hfaijPESgodEuoAd89Z31WYFuRRCKxAWWzjhXa+E5bBSUpMkuToLlgZgqiLmAmjfTJO9NOIM0i0+D/2foka4ALixhyklznefk8Dz2RwFb60luZSUE03NFoqp1/uifn6LB4r/Lery1wH8b1EN5rgjvJXDIRGsyaHWbtdQr0sB0NW6LoR5PzZPeq4X4DE6iBDzG7u55kFCFwVQXmxCgHN4bdniVHcu28m9piCTuvyGQHXZ2J6prsytv/N24ef/xBVTHMMx+bcj+AIB0z44/OfgK4DF2U4JURNsCmD9h6dY60Hi6kFHOe8Y9GcR8T9V2LrfOJdm2mX19U+ziCE7jo0zllxo6vzLCMwjfm61gWhxU30fOaZgXbhGHps3z/TS5LlYiLgZcv3LE+Ttvl3fl0Cm3SitvNqxwQTnLxxKjcr2+ZE523Azr6/6JF1t8wSBKz4MAH9FrNvHVbziu7QrrWOFpCUL22sbBXtglQvQ1fjHqQ84qcGh6fDJC9k3f+lWVX1jAQiJT6h2MjfwaSIbhUGFS1BG6mQ== + privateKeyString: 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 + notifyUrl: RIEeHCoPHaAryuVN6mEYskBSl+EPvhsxRpjIbuIE7f7jABVxm46bLc01WQUe4Fn9NPYyNTv0xCxM68iRrmFDjAUjQ/hkIVNG+yD/kNsjcYCWa2gtOQPrvWZzDA== justauth: enabled: true diff --git a/cf-module-system/cf-module-system-biz/src/main/resources/application-local.yaml b/cf-module-system/cf-module-system-biz/src/main/resources/application-local.yaml index fa79e5dd7..a0a55646e 100644 --- a/cf-module-system/cf-module-system-biz/src/main/resources/application-local.yaml +++ b/cf-module-system/cf-module-system-biz/src/main/resources/application-local.yaml @@ -291,12 +291,17 @@ chenfeng: privateKey: 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 alipayPublicKey: KbUGE7zsPBKWPx0/zMcAdLRldKrcgy2LRiOrqOBm7y4iPJLXTYtXFJT15p2JMQiyOM8mqiYQR0OEDwfrKxDgHXLtIut/e0EAk9bZwZoLrqVe0pN1huseRC38zEglbWil3yz+tZfHZuAaEq2EzvWJltX/tRKOzNBqAT9l+UvnqNedgCFB9MY2EErqJjbn/at3gYCkV2idt31ghF0z8SEQ5h9ztNYtmTvk8c8ipi0/hIjX8XryN6mlOvGQfyZ4rWrBWBuZ6iD/SyuThwxKmFYU4dhHbHVpBrva5nJWU43CP7RVaJm649nNJnce+Ppj2Tv8+ugSLe5poZWo2zmGe3Xn5WmN6OTZyRI1pnmn2/hGxtOMmTZJX7Gh0pI4v3wmU0gOd/gbRlqlvN+u12T92nyH8MQrHdA7UXuttAtolYUa/Rli/20qHX69QtOtvfZk8mNvDSj9dDvODseGcrFHm07jyfxpaIkQDeN75cQ3NwNgDQEW8urQszaU1IJ7hc+20tt0Z3td4+7MfiVPpGfVxsGE66gwLgpB8wsxEhyBTaBr7osMLqOv notifyUrl: RIEeHCoPHaAryuVN6mEYskBSl+EPvhsxRpjIbuIE7f7jABVxm46bLc01WQUe4Fn9NPYyNTv0xCxM68iRrmFDjAUjQ/hkIVNG+yD/kNsjcYCWa2gtOQPrvWZzDA== -# wechat: -# payBaseUrl: https://api.mch.weixin.qq.com/xdc/apiv2sandbox -# appId: wxd0b9c0b5d0b9c0b5 -# mchId: 1725093395 -# mchKey: Cf100261028910026102891002610289 - + wechat: + appId: vTVnNGeOPD8AeiTIS5cnUzq8q3EiOW0HZ18QtxFE/UxTYwV1DSwxrbYDbBGjoA== + mchId: p/zqgyb9tAG9n9DKROHdHuIv0FNQGfbQ0AH7uTsglakv9J4ZHGA= + mchKey: tdnmIOPmmqq0ST47xYWg61chgI2ycJGhjeApSjnraW103upgR/EMx/qfbFMVKA59BISqzbSukjQPV5pR + apiV3Key: tdnmIOPmmqq0ST47xYWg61chgI2ycJGhjeApSjnraW103upgR/EMx/qfbFMVKA59BISqzbSukjQPV5pR + publicKeyId: 9NU9NFR9WWUaN2xfCujfPhcOToJop6M0G4JGbpZDlkrfCQVK3KYDOEeinJwEuxvJGcoO2hKUVkapHmeUngH3VxPu+qBcf+gN8Q== + certSerialNo: zzAFIJnTSEhme+K37z/ciNI04S//eHxBR/VCKLdGRGTrWAlvHYU2LSw9YPl07OEBGOpIBHG3oep77cr5g8wpGXGRvJQ= + tradeType: eaQet/V56gw8fTCVKypLG8cAjgheMpxKo6Y6wQab1P5b9w== + publicKeyString: F+bPjhy/AwNvl16dMdqHCgKYIfA9c8Tho+g+fAeNOb7GjQf0NCX36B2ZH7yngpN6v82Q10/PfblVrPGrvMbDZcU4gxomhXN22L2hfaijPESgodEuoAd89Z31WYFuRRCKxAWWzjhXa+E5bBSUpMkuToLlgZgqiLmAmjfTJO9NOIM0i0+D/2foka4ALixhyklznefk8Dz2RwFb60luZSUE03NFoqp1/uifn6LB4r/Lery1wH8b1EN5rgjvJXDIRGsyaHWbtdQr0sB0NW6LoR5PzZPeq4X4DE6iBDzG7u55kFCFwVQXmxCgHN4bdniVHcu28m9piCTuvyGQHXZ2J6prsytv/N24ef/xBVTHMMx+bcj+AIB0z44/OfgK4DF2U4JURNsCmD9h6dY60Hi6kFHOe8Y9GcR8T9V2LrfOJdm2mX19U+ziCE7jo0zllxo6vzLCMwjfm61gWhxU30fOaZgXbhGHps3z/TS5LlYiLgZcv3LE+Ttvl3fl0Cm3SitvNqxwQTnLxxKjcr2+ZE523Azr6/6JF1t8wSBKz4MAH9FrNvHVbziu7QrrWOFpCUL22sbBXtglQvQ1fjHqQ84qcGh6fDJC9k3f+lWVX1jAQiJT6h2MjfwaSIbhUGFS1BG6mQ== + privateKeyString: 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 + notifyUrl: RIEeHCoPHaAryuVN6mEYskBSl+EPvhsxRpjIbuIE7f7jABVxm46bLc01WQUe4Fn9NPYyNTv0xCxM68iRrmFDjAUjQ/hkIVNG+yD/kNsjcYCWa2gtOQPrvWZzDA== justauth: enabled: true diff --git a/cf-module-system/cf-module-system-biz/src/main/resources/mapper/funds/purchase/PurchaseMapper.xml b/cf-module-system/cf-module-system-biz/src/main/resources/mapper/funds/purchase/PurchaseMapper.xml index cb17f577c..9879dd996 100644 --- a/cf-module-system/cf-module-system-biz/src/main/resources/mapper/funds/purchase/PurchaseMapper.xml +++ b/cf-module-system/cf-module-system-biz/src/main/resources/mapper/funds/purchase/PurchaseMapper.xml @@ -5,4 +5,14 @@ select sum(account_balance_spent) from purchase_record where organ_id = #{organId} and is_invocing = '${@com.cf.imes.module.system.enums.pay.InvoiceStatusEnum@INVOICABLE.status}'; + + + \ No newline at end of file