mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
1、发票抬头管理、可开票列表部分接口完善;2、微信支付发起和回调测试;
This commit is contained in:
@@ -78,6 +78,7 @@
|
|||||||
<jimureport.version>1.9.4</jimureport.version>
|
<jimureport.version>1.9.4</jimureport.version>
|
||||||
<xercesImpl.version>2.12.2</xercesImpl.version>
|
<xercesImpl.version>2.12.2</xercesImpl.version>
|
||||||
<weixin-java.version>4.7.5.B</weixin-java.version>
|
<weixin-java.version>4.7.5.B</weixin-java.version>
|
||||||
|
<weixin-pay-java.version>4.7.6.B</weixin-pay-java.version>
|
||||||
|
|
||||||
<!-- 拼音 -->
|
<!-- 拼音 -->
|
||||||
<pingyinfj.version>2.5.1</pingyinfj.version>
|
<pingyinfj.version>2.5.1</pingyinfj.version>
|
||||||
@@ -608,7 +609,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.binarywang</groupId>
|
<groupId>com.github.binarywang</groupId>
|
||||||
<artifactId>weixin-java-pay</artifactId>
|
<artifactId>weixin-java-pay</artifactId>
|
||||||
<version>${weixin-java.version}</version>
|
<version>${weixin-pay-java.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.binarywang</groupId>
|
<groupId>com.github.binarywang</groupId>
|
||||||
|
|||||||
+53
-5
@@ -19,6 +19,11 @@ public class ChenfengWechatPayConfig extends WxPayConfig {
|
|||||||
@Value("${chenfeng.encrypt.publicKey:}")
|
@Value("${chenfeng.encrypt.publicKey:}")
|
||||||
private String publicKey;
|
private String publicKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给微信支付的回调地址
|
||||||
|
*/
|
||||||
|
private String notifyUrl;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAppId(String appId) {
|
public void setAppId(String appId) {
|
||||||
if (StringUtils.isNotEmpty(publicKey)) {
|
if (StringUtils.isNotEmpty(publicKey)) {
|
||||||
@@ -47,13 +52,56 @@ public class ChenfengWechatPayConfig extends WxPayConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setKeyContent(byte[] keyContent) {
|
public void setApiV3Key(String apiV3Key) {
|
||||||
if (StringUtils.isNotEmpty(publicKey)) {
|
if (StringUtils.isNotEmpty(publicKey)) {
|
||||||
String encrypted = new String(keyContent, StandardCharsets.UTF_8);
|
super.setApiV3Key(AesUtils.decrypt(apiV3Key, publicKey));
|
||||||
String decrypted = AesUtils.decrypt(encrypted, publicKey);
|
|
||||||
super.setKeyContent(decrypted.getBytes(StandardCharsets.UTF_8));
|
|
||||||
} else {
|
} 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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -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 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_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 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 ============
|
//=========== 支付相关 1-002-048-000 ============
|
||||||
public static final ErrorCode PAY_CHANNEL_NOT_SUPPORT = new ErrorCode(1_002_048_000, "暂不支持的支付渠道,请使用其他支付渠道");
|
public static final ErrorCode PAY_CHANNEL_NOT_SUPPORT = new ErrorCode(1_002_048_000, "暂不支持的支付渠道,请使用其他支付渠道");
|
||||||
|
|||||||
+9
-5
@@ -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.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.controller.admin.funds.invoice.vo.InvoiceTitleReqVO;
|
||||||
import com.cf.imes.module.system.service.funds.invoice.InvoiceService;
|
import com.cf.imes.module.system.service.funds.invoice.InvoiceService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import org.springframework.validation.annotation.Validated;
|
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.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -32,15 +35,16 @@ public class InvoiceController {
|
|||||||
private InvoiceService invoiceService;
|
private InvoiceService invoiceService;
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("")
|
@PostMapping("/title")
|
||||||
@Operation(summary = "新增/修改发票抬头信息")
|
@Operation(summary = "新增/修改发票抬头信息")
|
||||||
public CommonResult<Boolean> insetInvoiceTitle(@Valid @RequestBody InvoiceTitleReqVO reqVO) {
|
public CommonResult<Boolean> insetInvoiceTitle(@Valid @RequestBody InvoiceTitleReqVO reqVO) {
|
||||||
|
|
||||||
invoiceService.insetInvoiceTitle(reqVO);
|
invoiceService.insetInvoiceTitle(reqVO);
|
||||||
|
|
||||||
return success(Boolean.TRUE);
|
return success(Boolean.TRUE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/available/info")
|
||||||
|
@Operation(summary = "获取组织的开票金额信息")
|
||||||
|
public CommonResult<InvoiceAmountAndAvailablePageRespVO> getInvoiceAmountAndAvailablePage(@Valid InvoiceAmountAndAvailablePageReqVO pageReqVO) {
|
||||||
|
return success(invoiceService.getInvoiceAmount(pageReqVO));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+29
@@ -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;
|
||||||
|
}
|
||||||
+20
@@ -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<PurchaseRecordDO> availableInvoicePurchaseRecords;
|
||||||
|
}
|
||||||
+23
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
+61
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+28
@@ -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<InvoicePurchaseRecord> invoicePurchaseRecords;
|
||||||
|
|
||||||
|
|
||||||
|
@Schema(description = "发票抬头信息")
|
||||||
|
private InvoiceTitleInfo invoiceTitleInfo;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+38
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
+55
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+15
@@ -1,7 +1,11 @@
|
|||||||
package com.cf.imes.module.system.controller.admin.funds.invoice.vo;
|
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 io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.Email;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
@@ -16,47 +20,58 @@ public class InvoiceTitleReqVO {
|
|||||||
|
|
||||||
|
|
||||||
@Schema(description = "组织ID")
|
@Schema(description = "组织ID")
|
||||||
|
@NotNull(message = "组织ID不能为空")
|
||||||
private Long organId;
|
private Long organId;
|
||||||
|
|
||||||
|
|
||||||
@Schema(description = "发票抬头")
|
@Schema(description = "发票抬头")
|
||||||
@NotBlank(message = "发票抬头不能为空")
|
@NotBlank(message = "发票抬头不能为空")
|
||||||
|
@Size(max = 64, message = "发票抬头长度不能超过64个字符")
|
||||||
private String invoiceTitle;
|
private String invoiceTitle;
|
||||||
|
|
||||||
|
|
||||||
@Schema(description = "开具类型,0企业 1个人")
|
@Schema(description = "开具类型,0企业 1个人")
|
||||||
@NotNull(message = "开具类型不能为空")
|
@NotNull(message = "开具类型不能为空")
|
||||||
|
@InvoiceIssueTypeValid
|
||||||
private Integer issueType;
|
private Integer issueType;
|
||||||
|
|
||||||
|
|
||||||
@Schema(description = "发票类型,0增值税普通发票 1增值税专用发票")
|
@Schema(description = "发票类型,0增值税普通发票 1增值税专用发票")
|
||||||
@NotNull(message = "发票类型不能为空")
|
@NotNull(message = "发票类型不能为空")
|
||||||
|
@InvoiceTypeValid
|
||||||
private Integer invoiceType;
|
private Integer invoiceType;
|
||||||
|
|
||||||
|
|
||||||
@Schema(description = "纳税人识别号")
|
@Schema(description = "纳税人识别号")
|
||||||
@NotNull(message = "纳税人识别号不能为空")
|
@NotNull(message = "纳税人识别号不能为空")
|
||||||
|
@Size(max = 20, message = "纳税人识别号长度不能超过20个字符")
|
||||||
private String taxpayerId;
|
private String taxpayerId;
|
||||||
|
|
||||||
|
|
||||||
@Schema(description = "开户银行名称")
|
@Schema(description = "开户银行名称")
|
||||||
|
@Size(max = 64, message = "开户银行名称长度不能超过64个字符")
|
||||||
private String bankName;
|
private String bankName;
|
||||||
|
|
||||||
|
|
||||||
@Schema(description = "开户银行账号")
|
@Schema(description = "开户银行账号")
|
||||||
|
@Size(max = 40, message = "开户银行账号长度不能超过40个字符")
|
||||||
private String bankAccount;
|
private String bankAccount;
|
||||||
|
|
||||||
|
|
||||||
@Schema(description = "注册场所地址")
|
@Schema(description = "注册场所地址")
|
||||||
|
@Size(max = 64, message = "注册场所地址长度不能超过64个字符")
|
||||||
private String registeredAddress;
|
private String registeredAddress;
|
||||||
|
|
||||||
|
|
||||||
@Schema(description = "注册固定电话")
|
@Schema(description = "注册固定电话")
|
||||||
|
@Size(max = 20, message = "注册固定电话长度不能超过20个字符")
|
||||||
private String fixedPhone;
|
private String fixedPhone;
|
||||||
|
|
||||||
|
|
||||||
@Schema(description = "邮箱")
|
@Schema(description = "邮箱")
|
||||||
@NotNull(message = "邮箱不能为空")
|
@NotNull(message = "邮箱不能为空")
|
||||||
|
@Size(max = 64, message = "邮箱长度不能超过64个字符")
|
||||||
|
@Email(message = "邮箱格式不正确")
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
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.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@@ -67,9 +68,10 @@ public class PayController {
|
|||||||
@PermitAll
|
@PermitAll
|
||||||
public String notifyOrder(@PathVariable("channelCode") Integer channelCode,
|
public String notifyOrder(@PathVariable("channelCode") Integer channelCode,
|
||||||
@RequestParam(required = false) Map<String, String> params,
|
@RequestParam(required = false) Map<String, String> params,
|
||||||
@RequestBody(required = false) String body) {
|
@RequestBody(required = false) String body,
|
||||||
log.info("[notifyOrder][channelCode({}) 回调数据({}/{})]", channelCode, params, body);
|
@RequestHeader Map<String, String> headers) {
|
||||||
payOrderService.doOrderNotify(channelCode, params, body);
|
log.info("[notifyOrder][channelCode({}) 回调数据({}/{}/{})]", channelCode, params, body, headers);
|
||||||
|
payOrderService.doOrderNotify(channelCode, params, body, headers);
|
||||||
// 支付接口回调相应必须是"success"
|
// 支付接口回调相应必须是"success"
|
||||||
return "success";
|
return "success";
|
||||||
}
|
}
|
||||||
|
|||||||
+30
@@ -1,10 +1,15 @@
|
|||||||
package com.cf.imes.module.system.dal.mysql.funds.purchase;
|
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.common.pojo.PageResult;
|
||||||
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
|
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
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.controller.admin.funds.purchase.vo.PurchaseRecordPageReqVO;
|
||||||
import com.cf.imes.module.system.dal.dataobject.funds.purchase.PurchaseRecordDO;
|
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 org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@@ -38,4 +43,29 @@ public interface PurchaseRecordMapper extends BaseMapperX<PurchaseRecordDO> {
|
|||||||
.likeIfPresent(PurchaseRecordDO::getCreator, pageReqVO.getCreator()));
|
.likeIfPresent(PurchaseRecordDO::getCreator, pageReqVO.getCreator()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询可开票记录
|
||||||
|
*
|
||||||
|
* @param pageReqVO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
default PageResult<PurchaseRecordDO> selectPage(InvoiceAmountAndAvailablePageReqVO pageReqVO) {
|
||||||
|
return selectPage(pageReqVO, new LambdaQueryWrapperX<PurchaseRecordDO>()
|
||||||
|
.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);
|
||||||
}
|
}
|
||||||
|
|||||||
+25
@@ -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;
|
||||||
|
}
|
||||||
+28
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -11,7 +11,7 @@ public class PayConstants {
|
|||||||
|
|
||||||
public static final String PAY_PASSBACK_PARAMS_KEY = "passback_params";// 回调参数passback key
|
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
|
public static final String PAY_PASSBACK_PARAMS_PURCHASE_RECORD_ID_KEY = "purchaseRecordId"; //支付passback 购买记录key
|
||||||
}
|
}
|
||||||
+26
@@ -1,6 +1,11 @@
|
|||||||
package com.cf.imes.module.system.service.funds.invoice;
|
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;
|
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 {
|
public interface InvoiceService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增/修改抬头信息
|
||||||
|
*
|
||||||
|
* @param reqVO
|
||||||
|
*/
|
||||||
void insetInvoiceTitle(InvoiceTitleReqVO reqVO);
|
void insetInvoiceTitle(InvoiceTitleReqVO reqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询组织开票金额和可开票列表
|
||||||
|
*
|
||||||
|
* @param invoiceAmountAndAvailablePageReqVO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
InvoiceAmountAndAvailablePageRespVO getInvoiceAmount(InvoiceAmountAndAvailablePageReqVO invoiceAmountAndAvailablePageReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询开票分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
PageResult<InvoiceDetailsRespVO> getInvoiceDetails(InvoiceDetailsPageReqVO pageReqVO);
|
||||||
}
|
}
|
||||||
|
|||||||
+76
-4
@@ -1,40 +1,55 @@
|
|||||||
package com.cf.imes.module.system.service.funds.invoice;
|
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.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.controller.admin.funds.invoice.vo.InvoiceTitleReqVO;
|
||||||
import com.cf.imes.module.system.dal.dataobject.funds.invoice.InvoiceTitleInfoDO;
|
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.invoice.InvoiceTitleInfoMapper;
|
||||||
|
import com.cf.imes.module.system.dal.mysql.funds.purchase.PurchaseRecordMapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
|
||||||
|
import static com.cf.imes.module.system.enums.ErrorCodeConstants.INVOICE_TITLE_NOT_EXISTS_ERROR;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author 发票管理接口 实现类
|
* @author 发票管理接口 实现类
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class InvoiceServiceImpl implements InvoiceService{
|
public class InvoiceServiceImpl implements InvoiceService {
|
||||||
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private InvoiceTitleInfoMapper invoiceTitleInfoMapper;
|
private InvoiceTitleInfoMapper invoiceTitleInfoMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PurchaseRecordMapper purchaseRecordMapper;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void insetInvoiceTitle(InvoiceTitleReqVO reqVO) {
|
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);
|
InvoiceTitleInfoDO titleInfoDO = BeanUtils.toBean(reqVO, InvoiceTitleInfoDO.class);
|
||||||
invoiceTitleInfoMapper.updateById(titleInfoDO);
|
invoiceTitleInfoMapper.updateById(titleInfoDO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增抬头
|
||||||
invoiceTitleInfoMapper.insert(InvoiceTitleInfoDO.builder()
|
invoiceTitleInfoMapper.insert(InvoiceTitleInfoDO.builder()
|
||||||
|
.organId(reqVO.getOrganId())
|
||||||
.invoiceTitle(reqVO.getInvoiceTitle())
|
.invoiceTitle(reqVO.getInvoiceTitle())
|
||||||
.invoiceType(reqVO.getInvoiceType())
|
.invoiceType(reqVO.getInvoiceType())
|
||||||
.issueType(reqVO.getIssueType())
|
.issueType(reqVO.getIssueType())
|
||||||
@@ -45,6 +60,63 @@ public class InvoiceServiceImpl implements InvoiceService{
|
|||||||
.fixedPhone(reqVO.getFixedPhone())
|
.fixedPhone(reqVO.getFixedPhone())
|
||||||
.email(reqVO.getEmail())
|
.email(reqVO.getEmail())
|
||||||
.build());
|
.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<InvoiceDetailsRespVO> getInvoiceDetails(InvoiceDetailsPageReqVO pageReqVO) {
|
||||||
|
//
|
||||||
|
// PageDTO<InvoiceDetailsRespVO> page = new PageDTO<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
|
||||||
|
//
|
||||||
|
// List<Integer> invoiceStatus = new ArrayList<>();
|
||||||
|
// invoiceStatus.add(InvoiceStatusEnum.INVOICABLE.getStatus());
|
||||||
|
// invoiceStatus.add(InvoiceStatusEnum.INVOICINGFAILED.getStatus());
|
||||||
|
//
|
||||||
|
// QueryWrapperX<IncomeExpenseDetailsDO> 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<InvoiceDetailsRespVO> respVOIPage = incomeExpenseDetailsMapper.selectOrganInvoicable(page, queryWrapperX);
|
||||||
|
//
|
||||||
|
// List<InvoiceDetailsRespVO> records = respVOIPage.getRecords();
|
||||||
|
// if (CollUtil.isEmpty(records)) {
|
||||||
|
// return new PageResult<>();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return new PageResult<>(records, respVOIPage.getTotal());
|
||||||
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ public interface PayOrderService {
|
|||||||
* @param body
|
* @param body
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
void doOrderNotify(Integer channelCode, Map<String, String> params, String body);
|
void doOrderNotify(Integer channelCode, Map<String, String> params, String body, Map<String, String> headers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理过期订单
|
* 处理过期订单
|
||||||
|
|||||||
+4
-6
@@ -1,7 +1,5 @@
|
|||||||
package com.cf.imes.module.system.service.pay;
|
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.IdUtil;
|
||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
@@ -320,7 +318,7 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|||||||
Long organId = SecurityFrameworkUtils.getUserOrganId();
|
Long organId = SecurityFrameworkUtils.getUserOrganId();
|
||||||
|
|
||||||
payOrderDO.setId(payOrderId);
|
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.setStatus(PayOrderStatusEnum.WAITING);
|
||||||
payOrderDO.setExpireTime(LocalDateTime.now().plus(payConfig.getPayExpireTime()));
|
payOrderDO.setExpireTime(LocalDateTime.now().plus(payConfig.getPayExpireTime()));
|
||||||
payOrderDO.setPrice(price);
|
payOrderDO.setPrice(price);
|
||||||
@@ -385,18 +383,18 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void doOrderNotify(Integer channelCode, Map<String, String> params, String body) {
|
public void doOrderNotify(Integer channelCode, Map<String, String> params, String body, Map<String, String> headers) {
|
||||||
// 获取渠道方处理器
|
// 获取渠道方处理器
|
||||||
AbstractPayHandler payHandler = payHandlerFactory.getPayHandler(channelCode);
|
AbstractPayHandler payHandler = payHandlerFactory.getPayHandler(channelCode);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 解析回调数据
|
// 解析回调数据
|
||||||
PayOrderRespDTO payOrderRespDTO = payHandler.doParseOrderNotify(params, body);
|
PayOrderRespDTO payOrderRespDTO = payHandler.doParseOrderNotify(params, body, headers);
|
||||||
|
|
||||||
// 处理支付回调数据
|
// 处理支付回调数据
|
||||||
this.notifyOrder(payOrderRespDTO);
|
this.notifyOrder(payOrderRespDTO);
|
||||||
} catch (Throwable e) {
|
} 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);
|
throw new PayException(PAY_ORDER_NOTIFY_DATA_PARSE_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -36,5 +36,5 @@ public abstract class AbstractPayHandler {
|
|||||||
* @param body
|
* @param body
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public abstract PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body) throws Throwable;
|
public abstract PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body, Map<String, String> headers) throws Throwable;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -108,7 +108,7 @@ public class AlipayPcPayHandler extends AbstractPayHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body) throws Throwable {
|
public PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body, Map<String, String> headers) throws Throwable {
|
||||||
// 1. 校验回调数据
|
// 1. 校验回调数据
|
||||||
verifyNotifyData(params);
|
verifyNotifyData(params);
|
||||||
|
|
||||||
|
|||||||
+66
-25
@@ -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.LocalDateTimeUtil;
|
||||||
import cn.hutool.core.date.TemporalAccessorUtil;
|
import cn.hutool.core.date.TemporalAccessorUtil;
|
||||||
|
import cn.hutool.core.text.CharSequenceUtil;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.cf.imes.framework.common.util.json.JsonUtils;
|
import com.cf.imes.framework.common.util.json.JsonUtils;
|
||||||
import com.cf.imes.framework.pay.config.ChenfengWechatPayConfig;
|
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.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
|
||||||
import com.cf.imes.module.system.enums.pay.PayOrderStatusEnum;
|
import com.cf.imes.module.system.enums.pay.PayOrderStatusEnum;
|
||||||
import com.cf.imes.module.system.service.pay.factory.impl.AbstractPayHandler;
|
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.notify.SignatureHeader;
|
||||||
import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult;
|
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result;
|
||||||
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
|
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.exception.WxPayException;
|
||||||
import com.github.binarywang.wxpay.service.WxPayService;
|
import com.github.binarywang.wxpay.service.WxPayService;
|
||||||
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
|
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
|
||||||
@@ -23,9 +25,9 @@ import org.springframework.stereotype.Service;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.Map;
|
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支付处理器
|
* 微信native支付处理器
|
||||||
@@ -43,22 +45,21 @@ public class WechatNativePayHandler extends AbstractPayHandler {
|
|||||||
@Override
|
@Override
|
||||||
public PayOrderRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
|
public PayOrderRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
|
||||||
// 构建 WxPayUnifiedOrderRequest 对象
|
// 构建 WxPayUnifiedOrderRequest 对象
|
||||||
WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder()
|
WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request();
|
||||||
.outTradeNo(reqDTO.getOutTradeNo())
|
request.setOutTradeNo(reqDTO.getOutTradeNo());
|
||||||
.body(reqDTO.getSubject())
|
request.setDescription(reqDTO.getSubject());
|
||||||
.detail(reqDTO.getBody())
|
request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getPrice())); // 单位分
|
||||||
.totalFee(reqDTO.getPrice()) // 单位分
|
request.setTimeExpire(formatDateV3(reqDTO.getExpireTime()));
|
||||||
.timeExpire(TemporalAccessorUtil.format(reqDTO.getExpireTime().atZone(ZoneId.systemDefault()), PURE_DATETIME_PATTERN))
|
request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(getClientIP()));
|
||||||
.spbillCreateIp(reqDTO.getUserIp())
|
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
||||||
.notifyUrl(reqDTO.getNotifyUrl())
|
request.setAttach(JSON.toJSONString(reqDTO.getPassbackParams()));
|
||||||
.attach(JSON.toJSONString(reqDTO.getPassbackParams()))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
|
// 加载配置,创建client
|
||||||
WxPayService client = new WxPayServiceImpl();
|
WxPayService client = new WxPayServiceImpl();
|
||||||
client.setConfig(chenfengWechatPayConfig);
|
client.setConfig(chenfengWechatPayConfig);
|
||||||
|
|
||||||
// 执行请求
|
// 执行请求
|
||||||
WxPayAppOrderResult response = client.createOrder(request);
|
String response = client.createOrderV3(TradeTypeEnum.NATIVE, request);
|
||||||
|
|
||||||
// 转换结果
|
// 转换结果
|
||||||
return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), JsonUtils.toJsonString(response),
|
return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), JsonUtils.toJsonString(response),
|
||||||
@@ -71,20 +72,60 @@ public class WechatNativePayHandler extends AbstractPayHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body) throws WxPayException {
|
public PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body, Map<String, String> headers) throws WxPayException {
|
||||||
// 1. 解析回调
|
// 1. 解析回调
|
||||||
|
SignatureHeader signatureHeader = getRequestHeader(headers);
|
||||||
|
// 加载配置,创建client
|
||||||
WxPayService client = new WxPayServiceImpl();
|
WxPayService client = new WxPayServiceImpl();
|
||||||
client.setConfig(chenfengWechatPayConfig);
|
client.setConfig(chenfengWechatPayConfig);
|
||||||
WxPayOrderNotifyResult response = client.parseOrderNotifyResult(body);
|
|
||||||
|
WxPayNotifyV3Result response = client.parseOrderNotifyV3Result(body, signatureHeader);
|
||||||
|
WxPayNotifyV3Result.DecryptNotifyResult result = response.getResult();
|
||||||
// 2. 构建结果
|
// 2. 构建结果
|
||||||
// V2 微信支付的回调,只有 SUCCESS 支付成功、CLOSED 支付失败两种情况,无需像支付宝一样解析的比较复杂
|
Integer status = parseStatus(result.getTradeState());
|
||||||
Integer status = Objects.equals(response.getResultCode(), "SUCCESS") ?
|
String openid = result.getPayer() != null ? result.getPayer().getOpenid() : null;
|
||||||
PayOrderStatusEnum.SUCCESS.getStatus() : PayOrderStatusEnum.FAIL.getStatus();
|
return PayOrderRespDTO.of(status, result.getTransactionId(), openid, parseDateV3(result.getSuccessTime()),
|
||||||
return PayOrderRespDTO.of(status, response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()),
|
result.getOutTradeNo(), body);
|
||||||
response.getOutTradeNo(), body);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static LocalDateTime parseDateV2(String time) {
|
static String formatDateV3(LocalDateTime time) {
|
||||||
return LocalDateTimeUtil.parse(time, PURE_DATETIME_PATTERN);
|
return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), UTC_WITH_XXX_OFFSET_PATTERN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组装请求头重的签名信息
|
||||||
|
*
|
||||||
|
* @see <a href="https://github.com/binarywang/weixin-java-pay-demo/blob/master/src/main/java/com/github/binarywang/demo/wx/pay/controller/WxPayV3Controller.java#L202-L221">官方示例</a>
|
||||||
|
*/
|
||||||
|
private SignatureHeader getRequestHeader(Map<String, String> 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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+32
@@ -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<? extends Payload>[] payload() default {};
|
||||||
|
}
|
||||||
+27
@@ -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<InvoiceIssueTypeValid, Integer> {
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
@@ -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<? extends Payload>[] payload() default {};
|
||||||
|
}
|
||||||
+27
@@ -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<InvoiceTypeValid, Integer> {
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -266,6 +266,17 @@ chenfeng:
|
|||||||
privateKey: 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
|
privateKey: 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
|
||||||
alipayPublicKey: KbUGE7zsPBKWPx0/zMcAdLRldKrcgy2LRiOrqOBm7y4iPJLXTYtXFJT15p2JMQiyOM8mqiYQR0OEDwfrKxDgHXLtIut/e0EAk9bZwZoLrqVe0pN1huseRC38zEglbWil3yz+tZfHZuAaEq2EzvWJltX/tRKOzNBqAT9l+UvnqNedgCFB9MY2EErqJjbn/at3gYCkV2idt31ghF0z8SEQ5h9ztNYtmTvk8c8ipi0/hIjX8XryN6mlOvGQfyZ4rWrBWBuZ6iD/SyuThwxKmFYU4dhHbHVpBrva5nJWU43CP7RVaJm649nNJnce+Ppj2Tv8+ugSLe5poZWo2zmGe3Xn5WmN6OTZyRI1pnmn2/hGxtOMmTZJX7Gh0pI4v3wmU0gOd/gbRlqlvN+u12T92nyH8MQrHdA7UXuttAtolYUa/Rli/20qHX69QtOtvfZk8mNvDSj9dDvODseGcrFHm07jyfxpaIkQDeN75cQ3NwNgDQEW8urQszaU1IJ7hc+20tt0Z3td4+7MfiVPpGfVxsGE66gwLgpB8wsxEhyBTaBr7osMLqOv
|
alipayPublicKey: KbUGE7zsPBKWPx0/zMcAdLRldKrcgy2LRiOrqOBm7y4iPJLXTYtXFJT15p2JMQiyOM8mqiYQR0OEDwfrKxDgHXLtIut/e0EAk9bZwZoLrqVe0pN1huseRC38zEglbWil3yz+tZfHZuAaEq2EzvWJltX/tRKOzNBqAT9l+UvnqNedgCFB9MY2EErqJjbn/at3gYCkV2idt31ghF0z8SEQ5h9ztNYtmTvk8c8ipi0/hIjX8XryN6mlOvGQfyZ4rWrBWBuZ6iD/SyuThwxKmFYU4dhHbHVpBrva5nJWU43CP7RVaJm649nNJnce+Ppj2Tv8+ugSLe5poZWo2zmGe3Xn5WmN6OTZyRI1pnmn2/hGxtOMmTZJX7Gh0pI4v3wmU0gOd/gbRlqlvN+u12T92nyH8MQrHdA7UXuttAtolYUa/Rli/20qHX69QtOtvfZk8mNvDSj9dDvODseGcrFHm07jyfxpaIkQDeN75cQ3NwNgDQEW8urQszaU1IJ7hc+20tt0Z3td4+7MfiVPpGfVxsGE66gwLgpB8wsxEhyBTaBr7osMLqOv
|
||||||
notifyUrl: VvJ5DOVuGOBw39j7tyrvsEEtLSseVM8T3u9kqsWKago+iI5ao8JzoggmeSe+N9LrsYxutK4fkGpmr4jOGJ3JTQFZ7YBXLxf2oLIXOZH9O27EnDtm
|
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:
|
justauth:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@@ -291,12 +291,17 @@ chenfeng:
|
|||||||
privateKey: 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
|
privateKey: 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
|
||||||
alipayPublicKey: KbUGE7zsPBKWPx0/zMcAdLRldKrcgy2LRiOrqOBm7y4iPJLXTYtXFJT15p2JMQiyOM8mqiYQR0OEDwfrKxDgHXLtIut/e0EAk9bZwZoLrqVe0pN1huseRC38zEglbWil3yz+tZfHZuAaEq2EzvWJltX/tRKOzNBqAT9l+UvnqNedgCFB9MY2EErqJjbn/at3gYCkV2idt31ghF0z8SEQ5h9ztNYtmTvk8c8ipi0/hIjX8XryN6mlOvGQfyZ4rWrBWBuZ6iD/SyuThwxKmFYU4dhHbHVpBrva5nJWU43CP7RVaJm649nNJnce+Ppj2Tv8+ugSLe5poZWo2zmGe3Xn5WmN6OTZyRI1pnmn2/hGxtOMmTZJX7Gh0pI4v3wmU0gOd/gbRlqlvN+u12T92nyH8MQrHdA7UXuttAtolYUa/Rli/20qHX69QtOtvfZk8mNvDSj9dDvODseGcrFHm07jyfxpaIkQDeN75cQ3NwNgDQEW8urQszaU1IJ7hc+20tt0Z3td4+7MfiVPpGfVxsGE66gwLgpB8wsxEhyBTaBr7osMLqOv
|
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==
|
notifyUrl: RIEeHCoPHaAryuVN6mEYskBSl+EPvhsxRpjIbuIE7f7jABVxm46bLc01WQUe4Fn9NPYyNTv0xCxM68iRrmFDjAUjQ/hkIVNG+yD/kNsjcYCWa2gtOQPrvWZzDA==
|
||||||
# wechat:
|
wechat:
|
||||||
# payBaseUrl: https://api.mch.weixin.qq.com/xdc/apiv2sandbox
|
appId: vTVnNGeOPD8AeiTIS5cnUzq8q3EiOW0HZ18QtxFE/UxTYwV1DSwxrbYDbBGjoA==
|
||||||
# appId: wxd0b9c0b5d0b9c0b5
|
mchId: p/zqgyb9tAG9n9DKROHdHuIv0FNQGfbQ0AH7uTsglakv9J4ZHGA=
|
||||||
# mchId: 1725093395
|
mchKey: tdnmIOPmmqq0ST47xYWg61chgI2ycJGhjeApSjnraW103upgR/EMx/qfbFMVKA59BISqzbSukjQPV5pR
|
||||||
# mchKey: Cf100261028910026102891002610289
|
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: P+7gYGAyY0lKxrzAowku4RCubro0QjTPX6IHP8oOmsgLnhzkF9EiWvyrcWrzHOsu6/JPrMM0NW7bC/2DSTmvGw9m2p8AI8syLT/1neQXJNq6N9TgbGVNfsYYsc2EKTmJhl1Y1ZuOEgze24n3HUmUwHCFUCc9LQQ5wHFhhVPwbyMEd7hHXnolEZ2qIBonCwX0bBX2NUHdHUDRHFBHbxDeypeA9G/Z9Wz1hkyRXAlPUdhnVhEVXb9/3ynvfLdCk4kTpZYR3D31y8d8jW+3PSGeWWZRkToEhCI2xbJto//8Lt13B9nPo3r5GZTj0M44nRsjEmDsbBXOC2Y1Nu0Bnx/C7JePcnEtOiLI1P4mf7e8vhXjzY4q6NZQ7D1NXF8U4x86izvy7dD/aaN0SCDnUaT91Xi3+h+eGMitWSrAHt634xkj81ijg56H+Q0hiUby0ejgwlgyGrO2Y1yh5umYvljPyKnUNagZJFmsG85yJ2CX4a5McGHitAAJhJzqwq2+bTIESd61TZCqIVDLV42AZMrEq25DXjgFwoBD5tnbh8EMIGhAWIXMTbEKQy5NV5bWbY/w4XUSl16v6K6W3RtgK8UANAoipIOcaReQ/25lxRN2C6tbPoRnG4ddHUj2J5/fG9X3FfJ1BVBqopCtzp/vnntq+73DgQy3dthB7EA1cCgHzlPGdTTe6O6N7gMwjA2SdtFTQtxEX6Pi8JhjuEF5zSsMvs1CWxh3l/mRFCwQw3qrEU/q1CFeIWQF2o3swhXPjcNWz38zPdFTvADsXz+GowN2IsQdq/uvRHFqBSyEMBcEGyn5VqRcmcB5Rk0L6dD3lKGOn/9H+3z+s2Ljf9dXdXm9jv/Nld20klrQs0ySwmIcbWra7vD4iUwNEx+F/QoeDsAI3OhUGaaoir+dJ6pjwFZO/A3P20dseZLRVlvGCE6cFVfJenv4pBTpOmKTFiLKsqyk3MykaDwRwSvCLI0NHKDI+ckgiTHTVoL+0gjjVtKlyFJk0whY6lu7lObNKj+DbDmetWMa1EWhzcscVX1f6dzTRRo9GjL+SFQT4s1dGjQ9lOpmP1ICP6X5C9MuJ/y2ScZ7ywSkrqmnxAPi122T8hVDRL/HwqxneKP3oWl1DlDHcQoAQqo8iwRDs9e2gta48g4J/NyX2FJ76I2F86L//qhuKq0uSXQTr6ara4eKeFi8fjdbipEOsvP6wEQEFegH//7o/Fta7wxj3Lt81fEqJ9XOuCW+1x6xtXowlhjNM+qF1cGNa5Jd5ATfTd3KH0ClgNk8pki8q26jRpyOChCCoZg5a1CqyzbFFaXYYNmtuuwUSgbOUIDLFtmJgpoj95oDyBzYbzPzTV26jvJIBpiM6BWFKGBcDXUPPUTGCCZo/QDIDeBBF1Ar52i5QDWUWYEwKBQ70llN4AByy+tPtqhoLNfDiNvEDMxXEOh+beB3U5wUKMm4f3TP2VpGjgYBMCNwoV4v/iNhDrdvzmhmRYUDCTF1ttn2LlFKAO+Yba7IPwAjHMGHZ7pm6/bJ/bAAi57Kr7C5sO38Ovi7ilkn2yXC4ZOCZe0En7n3AUyGwvcDB7RkW08U6mVMKHr8mKT8wpt0ia1IJDmuHMO7r6dJWMimIBeY+eo8R3/NZY7hLyLd0mz+onq+nYYSJBzXG1J0I9VYcU7T7/RMk+pt6W1Jb3jkd+oytK0LANumN4Tb4ufnJevYyq3wRiQV5V7aZNyvPWLQigdc2Q3MkmZ8PCTcRDnhVw8h7WxgvwiArKe2ThF7UdFEa8cnyp7ATu77fw1DlIyzLFscOiOleBp67+e+kEzXNoQkGKsBxkBZrfK03fw5+8SMB/59c7UB6Ym92BO9U8CyrwyoDq9Im75wPDXR3KedjBLvbpEOBQsf2v0a3CUfIdpCP4r9R2SGKK3PAsl1/I+/5/ICF+7wHpmZMg4DO5CqpKGnHop4qkg/JXbTpeKeCrZpMZXVJxsr/4a4wHGWl+LqbUFhwfUS+9dRGXnx047g+lDLBp2evHE2w11wlLJeDW/5tmxDAzqb3fI9ZMAFfhkj8jkAL6HtNMg3iDevp9F42pgHkrdkXcChTsQWfKNMqKjRkfscgmVvtcnPHTbke8F8UlKqRAWaTKpir9xpbhvD53eNDktjC5cwKG/k7vj3etojBzhGO3txtHlTzSMBO/Mjf7guTNVyb5f+DTSjYhjLvYVKBtH1dlXlFW/V1xefyVxrKynPaNzid4kPWLd7j8d3JbMv+/JlZRxTT2CUskLtrBH1xg7RNRx6sKtmBd+wE7jMwhCvzIa00OBqKwJZk1jcqWtcwKPm7y14eg==
|
||||||
|
notifyUrl: RIEeHCoPHaAryuVN6mEYskBSl+EPvhsxRpjIbuIE7f7jABVxm46bLc01WQUe4Fn9NPYyNTv0xCxM68iRrmFDjAUjQ/hkIVNG+yD/kNsjcYCWa2gtOQPrvWZzDA==
|
||||||
|
|
||||||
justauth:
|
justauth:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
+10
@@ -5,4 +5,14 @@
|
|||||||
select sum(account_balance_spent) from purchase_record
|
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}';
|
where organ_id = #{organId} and is_invocing = '${@com.cf.imes.module.system.enums.pay.InvoiceStatusEnum@INVOICABLE.status}';
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询机构下开票金额统计:可开票、开票中、已开票-->
|
||||||
|
<select id="getOrgInvoiceAmountStatistics" resultType="com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceAmountRespVO">
|
||||||
|
select organ_id,
|
||||||
|
sum(case when is_invocing = '${@com.cf.imes.module.system.enums.pay.InvoiceStatusEnum@INVOICABLE.status}' then account_balance_spent else 0 end) as invocable,
|
||||||
|
sum(case when is_invocing = '${@com.cf.imes.module.system.enums.pay.InvoiceStatusEnum@PENDINGINVOICING.status}' then account_balance_spent else 0 end) as inTheInvoice,
|
||||||
|
sum(case when is_invocing = '${@com.cf.imes.module.system.enums.pay.InvoiceStatusEnum@INVOICINGSUCCESSFUL.status}' then account_balance_spent else 0 end) as invoiced
|
||||||
|
from purchase_record
|
||||||
|
where organ_id = #{organId}
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
Reference in New Issue
Block a user