feat: 增加了 openapi spec
diff --git a/build.gradle b/build.gradle
index 0e2feff..7187f27 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,7 @@
id 'org.jetbrains.kotlin.plugin.jpa' version '1.3.31' apply false
id "com.palantir.git-version" version "0.12.2"
id 'com.palantir.docker' version '0.22.2' apply false
+ id "org.openapi.generator" version "4.2.2" apply false
}
bootJar {
@@ -101,6 +102,9 @@
springSocialVersion = '1.1.6.RELEASE'
springKafkaVersion = '2.2.8.RELEASE'
postgresVersion = '42.2.5'
+ openapitoolsVersion = '0.1.0'
+ swaggerVersion = '1.6.0'
+ springfoxVersion = '2.9.2'
multiTenantLibVersion = '1.3.2'
}
implementation "org.jetbrains.kotlin:kotlin-reflect"
diff --git a/payapi-common/build.gradle b/payapi-common/build.gradle
index ee97798..ba8d004 100644
--- a/payapi-common/build.gradle
+++ b/payapi-common/build.gradle
@@ -32,6 +32,11 @@
implementation "commons-beanutils:commons-beanutils:${beanutilsVersion}"
implementation "commons-codec:commons-codec:${codecVersion}"
implementation "org.apache.commons:commons-lang3:${lang3Version}"
+ implementation "org.springframework:spring-web"
+ implementation group: 'io.swagger', name: 'swagger-annotations', version: swaggerVersion
+
+ implementation "org.openapitools:jackson-databind-nullable:${openapitoolsVersion}"
+
compileOnly "org.projectlombok:lombok:${lombokVersion}"
annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodeFormat.java b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodeFormat.java
new file mode 100644
index 0000000..1f0adda
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodeFormat.java
@@ -0,0 +1,44 @@
+package com.supwisdom.dlpay.payapi.model;
+
+import java.util.Objects;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.openapitools.jackson.nullable.JsonNullable;
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+/**
+ * Gets or Sets QrcodeFormat
+ */
+public enum QrcodeFormat {
+
+ PLAIN("plain"),
+
+ BASE64("base64"),
+
+ HEX("hex");
+
+ private String value;
+
+ QrcodeFormat(String value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public String toString() {
+ return String.valueOf(value);
+ }
+
+ @JsonCreator
+ public static QrcodeFormat fromValue(String value) {
+ for (QrcodeFormat b : QrcodeFormat.values()) {
+ if (b.value.equals(value)) {
+ return b;
+ }
+ }
+ throw new IllegalArgumentException("Unexpected value '" + value + "'");
+ }
+}
+
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayConfirmRequest.java b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayConfirmRequest.java
new file mode 100644
index 0000000..51685c4
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayConfirmRequest.java
@@ -0,0 +1,307 @@
+package com.supwisdom.dlpay.payapi.model;
+
+import java.util.Objects;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.supwisdom.dlpay.payapi.model.QrcodeFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.openapitools.jackson.nullable.JsonNullable;
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+
+/**
+ * QrcodePayConfirmRequest
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2020-03-12T16:09:45.966+08:00[Asia/Shanghai]")
+
+public class QrcodePayConfirmRequest {
+ @JsonProperty("billno")
+ private String billno;
+
+ @JsonProperty("shopaccno")
+ private String shopaccno;
+
+ @JsonProperty("transDate")
+ private String transDate;
+
+ @JsonProperty("transTime")
+ private String transTime;
+
+ @JsonProperty("dlttype")
+ private String dlttype;
+
+ @JsonProperty("amount")
+ private Integer amount;
+
+ @JsonProperty("userid")
+ private String userid;
+
+ @JsonProperty("anonymous")
+ private Boolean anonymous;
+
+ @JsonProperty("qrcode")
+ private String qrcode;
+
+ @JsonProperty("qrcodeFormat")
+ private QrcodeFormat qrcodeFormat;
+
+ public QrcodePayConfirmRequest billno(String billno) {
+ this.billno = billno;
+ return this;
+ }
+
+ /**
+ * Get billno
+ * @return billno
+ */
+ @ApiModelProperty(value = "")
+
+@Pattern(regexp="[0-9]*") @Size(min=16)
+ public String getBillno() {
+ return billno;
+ }
+
+ public void setBillno(String billno) {
+ this.billno = billno;
+ }
+
+ public QrcodePayConfirmRequest shopaccno(String shopaccno) {
+ this.shopaccno = shopaccno;
+ return this;
+ }
+
+ /**
+ * Get shopaccno
+ * @return shopaccno
+ */
+ @ApiModelProperty(value = "")
+
+@Pattern(regexp="[0-9]*")
+ public String getShopaccno() {
+ return shopaccno;
+ }
+
+ public void setShopaccno(String shopaccno) {
+ this.shopaccno = shopaccno;
+ }
+
+ public QrcodePayConfirmRequest transDate(String transDate) {
+ this.transDate = transDate;
+ return this;
+ }
+
+ /**
+ * Get transDate
+ * @return transDate
+ */
+ @ApiModelProperty(value = "")
+
+@Pattern(regexp="[0-9]*") @Size(min=8,max=8)
+ public String getTransDate() {
+ return transDate;
+ }
+
+ public void setTransDate(String transDate) {
+ this.transDate = transDate;
+ }
+
+ public QrcodePayConfirmRequest transTime(String transTime) {
+ this.transTime = transTime;
+ return this;
+ }
+
+ /**
+ * Get transTime
+ * @return transTime
+ */
+ @ApiModelProperty(value = "")
+
+@Pattern(regexp="[0-9]*") @Size(min=6,max=6)
+ public String getTransTime() {
+ return transTime;
+ }
+
+ public void setTransTime(String transTime) {
+ this.transTime = transTime;
+ }
+
+ public QrcodePayConfirmRequest dlttype(String dlttype) {
+ this.dlttype = dlttype;
+ return this;
+ }
+
+ /**
+ * Get dlttype
+ * @return dlttype
+ */
+ @ApiModelProperty(value = "")
+
+
+ public String getDlttype() {
+ return dlttype;
+ }
+
+ public void setDlttype(String dlttype) {
+ this.dlttype = dlttype;
+ }
+
+ public QrcodePayConfirmRequest amount(Integer amount) {
+ this.amount = amount;
+ return this;
+ }
+
+ /**
+ * Get amount
+ * @return amount
+ */
+ @ApiModelProperty(value = "")
+
+
+ public Integer getAmount() {
+ return amount;
+ }
+
+ public void setAmount(Integer amount) {
+ this.amount = amount;
+ }
+
+ public QrcodePayConfirmRequest userid(String userid) {
+ this.userid = userid;
+ return this;
+ }
+
+ /**
+ * Get userid
+ * @return userid
+ */
+ @ApiModelProperty(value = "")
+
+
+ public String getUserid() {
+ return userid;
+ }
+
+ public void setUserid(String userid) {
+ this.userid = userid;
+ }
+
+ public QrcodePayConfirmRequest anonymous(Boolean anonymous) {
+ this.anonymous = anonymous;
+ return this;
+ }
+
+ /**
+ * Get anonymous
+ * @return anonymous
+ */
+ @ApiModelProperty(value = "")
+
+
+ public Boolean getAnonymous() {
+ return anonymous;
+ }
+
+ public void setAnonymous(Boolean anonymous) {
+ this.anonymous = anonymous;
+ }
+
+ public QrcodePayConfirmRequest qrcode(String qrcode) {
+ this.qrcode = qrcode;
+ return this;
+ }
+
+ /**
+ * Get qrcode
+ * @return qrcode
+ */
+ @ApiModelProperty(value = "")
+
+
+ public String getQrcode() {
+ return qrcode;
+ }
+
+ public void setQrcode(String qrcode) {
+ this.qrcode = qrcode;
+ }
+
+ public QrcodePayConfirmRequest qrcodeFormat(QrcodeFormat qrcodeFormat) {
+ this.qrcodeFormat = qrcodeFormat;
+ return this;
+ }
+
+ /**
+ * Get qrcodeFormat
+ * @return qrcodeFormat
+ */
+ @ApiModelProperty(value = "")
+
+ @Valid
+
+ public QrcodeFormat getQrcodeFormat() {
+ return qrcodeFormat;
+ }
+
+ public void setQrcodeFormat(QrcodeFormat qrcodeFormat) {
+ this.qrcodeFormat = qrcodeFormat;
+ }
+
+
+ @Override
+ public boolean equals(java.lang.Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ QrcodePayConfirmRequest qrcodePayConfirmRequest = (QrcodePayConfirmRequest) o;
+ return Objects.equals(this.billno, qrcodePayConfirmRequest.billno) &&
+ Objects.equals(this.shopaccno, qrcodePayConfirmRequest.shopaccno) &&
+ Objects.equals(this.transDate, qrcodePayConfirmRequest.transDate) &&
+ Objects.equals(this.transTime, qrcodePayConfirmRequest.transTime) &&
+ Objects.equals(this.dlttype, qrcodePayConfirmRequest.dlttype) &&
+ Objects.equals(this.amount, qrcodePayConfirmRequest.amount) &&
+ Objects.equals(this.userid, qrcodePayConfirmRequest.userid) &&
+ Objects.equals(this.anonymous, qrcodePayConfirmRequest.anonymous) &&
+ Objects.equals(this.qrcode, qrcodePayConfirmRequest.qrcode) &&
+ Objects.equals(this.qrcodeFormat, qrcodePayConfirmRequest.qrcodeFormat);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(billno, shopaccno, transDate, transTime, dlttype, amount, userid, anonymous, qrcode, qrcodeFormat);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class QrcodePayConfirmRequest {\n");
+
+ sb.append(" billno: ").append(toIndentedString(billno)).append("\n");
+ sb.append(" shopaccno: ").append(toIndentedString(shopaccno)).append("\n");
+ sb.append(" transDate: ").append(toIndentedString(transDate)).append("\n");
+ sb.append(" transTime: ").append(toIndentedString(transTime)).append("\n");
+ sb.append(" dlttype: ").append(toIndentedString(dlttype)).append("\n");
+ sb.append(" amount: ").append(toIndentedString(amount)).append("\n");
+ sb.append(" userid: ").append(toIndentedString(userid)).append("\n");
+ sb.append(" anonymous: ").append(toIndentedString(anonymous)).append("\n");
+ sb.append(" qrcode: ").append(toIndentedString(qrcode)).append("\n");
+ sb.append(" qrcodeFormat: ").append(toIndentedString(qrcodeFormat)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(java.lang.Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+}
+
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayInitRequest.java b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayInitRequest.java
new file mode 100644
index 0000000..cdb426d
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayInitRequest.java
@@ -0,0 +1,212 @@
+package com.supwisdom.dlpay.payapi.model;
+
+import java.util.Objects;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.supwisdom.dlpay.payapi.model.QrcodeFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.openapitools.jackson.nullable.JsonNullable;
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+
+/**
+ * QrcodePayInitRequest
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2020-03-12T16:09:45.966+08:00[Asia/Shanghai]")
+
+public class QrcodePayInitRequest {
+ @JsonProperty("qrcode")
+ private String qrcode;
+
+ @JsonProperty("transDate")
+ private String transDate;
+
+ @JsonProperty("transTime")
+ private String transTime;
+
+ @JsonProperty("shopaccno")
+ private String shopaccno;
+
+ @JsonProperty("billno")
+ private String billno;
+
+ @JsonProperty("qrcodeFormat")
+ private QrcodeFormat qrcodeFormat;
+
+ public QrcodePayInitRequest qrcode(String qrcode) {
+ this.qrcode = qrcode;
+ return this;
+ }
+
+ /**
+ * Get qrcode
+ * @return qrcode
+ */
+ @ApiModelProperty(required = true, value = "")
+ @NotNull
+
+
+ public String getQrcode() {
+ return qrcode;
+ }
+
+ public void setQrcode(String qrcode) {
+ this.qrcode = qrcode;
+ }
+
+ public QrcodePayInitRequest transDate(String transDate) {
+ this.transDate = transDate;
+ return this;
+ }
+
+ /**
+ * Get transDate
+ * @return transDate
+ */
+ @ApiModelProperty(required = true, value = "")
+ @NotNull
+
+@Pattern(regexp="[0-9]*") @Size(min=8,max=8)
+ public String getTransDate() {
+ return transDate;
+ }
+
+ public void setTransDate(String transDate) {
+ this.transDate = transDate;
+ }
+
+ public QrcodePayInitRequest transTime(String transTime) {
+ this.transTime = transTime;
+ return this;
+ }
+
+ /**
+ * Get transTime
+ * @return transTime
+ */
+ @ApiModelProperty(required = true, value = "")
+ @NotNull
+
+@Pattern(regexp="[0-9]*") @Size(min=6,max=6)
+ public String getTransTime() {
+ return transTime;
+ }
+
+ public void setTransTime(String transTime) {
+ this.transTime = transTime;
+ }
+
+ public QrcodePayInitRequest shopaccno(String shopaccno) {
+ this.shopaccno = shopaccno;
+ return this;
+ }
+
+ /**
+ * Get shopaccno
+ * @return shopaccno
+ */
+ @ApiModelProperty(required = true, value = "")
+ @NotNull
+
+@Pattern(regexp="[0-9]*")
+ public String getShopaccno() {
+ return shopaccno;
+ }
+
+ public void setShopaccno(String shopaccno) {
+ this.shopaccno = shopaccno;
+ }
+
+ public QrcodePayInitRequest billno(String billno) {
+ this.billno = billno;
+ return this;
+ }
+
+ /**
+ * Get billno
+ * @return billno
+ */
+ @ApiModelProperty(required = true, value = "")
+ @NotNull
+
+@Pattern(regexp="[0-9]*") @Size(min=16)
+ public String getBillno() {
+ return billno;
+ }
+
+ public void setBillno(String billno) {
+ this.billno = billno;
+ }
+
+ public QrcodePayInitRequest qrcodeFormat(QrcodeFormat qrcodeFormat) {
+ this.qrcodeFormat = qrcodeFormat;
+ return this;
+ }
+
+ /**
+ * Get qrcodeFormat
+ * @return qrcodeFormat
+ */
+ @ApiModelProperty(value = "")
+
+ @Valid
+
+ public QrcodeFormat getQrcodeFormat() {
+ return qrcodeFormat;
+ }
+
+ public void setQrcodeFormat(QrcodeFormat qrcodeFormat) {
+ this.qrcodeFormat = qrcodeFormat;
+ }
+
+
+ @Override
+ public boolean equals(java.lang.Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ QrcodePayInitRequest qrcodePayInitRequest = (QrcodePayInitRequest) o;
+ return Objects.equals(this.qrcode, qrcodePayInitRequest.qrcode) &&
+ Objects.equals(this.transDate, qrcodePayInitRequest.transDate) &&
+ Objects.equals(this.transTime, qrcodePayInitRequest.transTime) &&
+ Objects.equals(this.shopaccno, qrcodePayInitRequest.shopaccno) &&
+ Objects.equals(this.billno, qrcodePayInitRequest.billno) &&
+ Objects.equals(this.qrcodeFormat, qrcodePayInitRequest.qrcodeFormat);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(qrcode, transDate, transTime, shopaccno, billno, qrcodeFormat);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class QrcodePayInitRequest {\n");
+
+ sb.append(" qrcode: ").append(toIndentedString(qrcode)).append("\n");
+ sb.append(" transDate: ").append(toIndentedString(transDate)).append("\n");
+ sb.append(" transTime: ").append(toIndentedString(transTime)).append("\n");
+ sb.append(" shopaccno: ").append(toIndentedString(shopaccno)).append("\n");
+ sb.append(" billno: ").append(toIndentedString(billno)).append("\n");
+ sb.append(" qrcodeFormat: ").append(toIndentedString(qrcodeFormat)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(java.lang.Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+}
+
diff --git a/payapi-spec/build.gradle b/payapi-spec/build.gradle
new file mode 100644
index 0000000..c4bc7c9
--- /dev/null
+++ b/payapi-spec/build.gradle
@@ -0,0 +1,54 @@
+plugins {
+ id 'java-library'
+ id 'org.springframework.boot'
+ id "org.openapi.generator"
+}
+
+apply plugin: 'io.spring.dependency-management'
+
+
+dependencies {
+ implementation "org.springframework.boot:spring-boot-autoconfigure"
+}
+
+bootJar {
+ enabled = false
+}
+
+openApiGenerate {
+ generatorName = "spring"
+ inputSpec = "$projectDir/payapi-spec.yaml".toString()
+ outputDir = "$buildDir/generated".toString()
+ apiPackage = "com.supwisdom.dlpay.api"
+ invokerPackage = "com.supwisdom.dlpay.payapi"
+ modelPackage = "com.supwisdom.dlpay.payapi.model"
+
+ configOptions = [
+ dateLibrary : "java8",
+ artifactDescription : "PayAPI API",
+ developerName : "Supwisdom",
+ developerEmail : "admin@supwisdom.com",
+ developerOrganization : "Supwisdom Tech Inc.",
+ developerOrganizationUrl: "http://www.supwisdom.com",
+ java8 : "true",
+ interfaceOnly : "true",
+ generateAliasAsModel : "false"
+ ]
+}
+
+task copyApiSrc(type: Copy) {
+ from("$buildDir/generated/src/main/java/com/supwisdom/dlpay/api") {
+ include "**/*.java"
+ }
+ into "$rootProject.projectDir/payapi/src/main/java/com/supwisdom/dlpay/api"
+
+
+}
+task copyModelSrc(type: Copy) {
+ from("$buildDir/generated/src/main/java/com/supwisdom/dlpay/payapi/model") {
+ include "**/*.java"
+ }
+ into "$rootProject.projectDir/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model"
+}
+
+//copySrc.dependsOn openApiGenerate
\ No newline at end of file
diff --git a/payapi-spec/consumeapi.yaml b/payapi-spec/consumeapi.yaml
new file mode 100644
index 0000000..4d62dd5
--- /dev/null
+++ b/payapi-spec/consumeapi.yaml
@@ -0,0 +1,188 @@
+components:
+ schemas:
+ ErrorResponse:
+ type: object
+ title: 请求错误
+ required:
+ - message
+ properties:
+ code:
+ type: string
+ title: 错误码
+ message:
+ type: string
+ title: 错误信息
+ QrcodePayInitRequest:
+ type: object
+ title: QrCode请求初始化
+ required:
+ - qrcode
+ - transDate
+ - transTime
+ - shopaccno
+ - billno
+ properties:
+ qrcode:
+ type: string
+ title: QrCode
+ transDate:
+ $ref: 'definitions.yaml#/components/schemas/TransDate'
+ transTime:
+ $ref: 'definitions.yaml#/components/schemas/TransTime'
+ shopaccno:
+ $ref: 'definitions.yaml#/components/schemas/ShopAccNo'
+ billno:
+ $ref: 'definitions.yaml#/components/schemas/Refno'
+ qrcodeFormat:
+ $ref: 'definitions.yaml#/components/schemas/QrcodeFormat'
+
+ QrcodePayInitResponse:
+ type: object
+ title: QrCode请求初始化应答
+ properties:
+ anonymous:
+ title: 是否匿名用户
+ type: boolean
+ userid:
+ title: 用户ID(非匿名)
+ type: string
+ username:
+ title: 用户名(非匿名)
+ type: string
+ sourcetype:
+ title: 支付方式
+ type: string
+ QrcodePayConfirmRequest:
+ type: object
+ title: Qrcode消费确认请求
+ properties:
+ billno:
+ $ref: 'definitions.yaml#/components/schemas/Refno'
+ shopaccno:
+ $ref: 'definitions.yaml#/components/schemas/ShopAccNo'
+ transDate:
+ $ref: 'definitions.yaml#/components/schemas/TransDate'
+ transTime:
+ $ref: 'definitions.yaml#/components/schemas/TransTime'
+ dlttype:
+ type: string
+ title: 交易类型
+ amount:
+ type: integer
+ format: int32
+ title: 交易金额
+ userid:
+ type: string
+ title: 用户ID(非匿名)
+ anonymous:
+ type: boolean
+ title: 是否匿名
+ qrcode:
+ type: string
+ title: QrCode
+ qrcodeFormat:
+ $ref: 'definitions.yaml#/components/schemas/QrcodeFormat'
+ QrcodePayConfirmResponse:
+ type: object
+ title: QrCode消费确认返回
+ properties:
+ refno:
+ $ref: 'definitions.yaml#/components/schemas/Refno'
+ hostDate:
+ $ref: 'definitions.yaml#/components/schemas/TransDate'
+ hostTime:
+ $ref: 'definitions.yaml#/components/schemas/TransTime'
+ description:
+ type: string
+ title: 交易描述
+ result:
+ title: 交易结果
+ type: string
+ enum:
+ - success
+ - require_query
+ - already_success
+ - failed
+
+ paths:
+ qrcodePayInit:
+ parameters:
+ - $ref: definitions.yaml#/components/headers/TenantId
+ post:
+ operationId: qrcodePayInit
+ tags:
+ - pos
+ requestBody:
+ description: QrCode 初始化
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/QrcodePayInitRequest'
+
+ responses:
+ '200':
+ description: 初始化成功
+ content:
+ application/json:
+ $ref: '#/components/schemas/QrcodePayInitResponse'
+ 'default':
+ description: 请求错误
+ content:
+ application/json:
+ $ref: '#/components/schemas/ErrorResponse'
+ qrcodePayConfirm:
+ parameters:
+ - $ref: definitions.yaml#/components/headers/TenantId
+ post:
+ operationId: qrcodePayConfirm
+ tags:
+ - pos
+ requestBody:
+ description: Qrcode确认
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/QrcodePayConfirmRequest'
+ responses:
+ '200':
+ description: 交易成功
+ content:
+ application/json:
+ $ref: '#/components/schemas/QrcodePayConfirmResponse'
+ '409':
+ description: 交易正忙,稍后重试
+ content:
+ application/json:
+ $ref: '#/components/schemas/ErrorResponse'
+ 'default':
+ description: 交易失败
+ content:
+ application/json:
+ $ref: '#/components/schemas/ErrorResponse'
+ qrcodePayQuery:
+ parameters:
+ - $ref: 'definitions.yaml#/components/headers/TenantId'
+ - name: refno
+ in: path
+ description: 系统交易参考号
+ required: true
+ schema:
+ type: string
+ title: 系统交易参考号
+ get:
+ description: 根据系统交易参考号查询流水状态
+ tags:
+ - pos
+ operationId: qrcodePayQuery
+ responses:
+ '200':
+ description: 查询成功
+ content:
+ application/json:
+ $ref: '#/components/schemas/QrcodePayConfirmResponse'
+ 'default':
+ description: 查询失败
+ content:
+ application/json:
+ $ref: '#/components/schemas/ErrorResponse'
+
diff --git a/payapi-spec/definitions.yaml b/payapi-spec/definitions.yaml
new file mode 100644
index 0000000..fea5324
--- /dev/null
+++ b/payapi-spec/definitions.yaml
@@ -0,0 +1,40 @@
+components:
+ headers:
+ TenantId:
+ name: X-Tenant-Id
+ in: header
+ description: 租户ID
+ required: true
+ schema:
+ type: string
+
+
+ schemas:
+ TransDate:
+ type: string
+ title: 交易日期
+ minLength: 8
+ maxLength: 8
+ pattern: '[0-9]*'
+ TransTime:
+ type: string
+ title: 交易时间
+ minLength: 6
+ maxLength: 6
+ pattern: '[0-9]*'
+ ShopAccNo:
+ type: string
+ title: 商户号
+ pattern: '[0-9]*'
+ Refno:
+ type: string
+ title: 交易号
+ minLength: 16
+ pattern: '[0-9]*'
+ QrcodeFormat:
+ type: string
+ title: Qrcode格式
+ enum:
+ - plain
+ - base64
+ - hex
diff --git a/payapi-spec/payapi-spec.yaml b/payapi-spec/payapi-spec.yaml
new file mode 100644
index 0000000..1b432bc
--- /dev/null
+++ b/payapi-spec/payapi-spec.yaml
@@ -0,0 +1,13 @@
+openapi: '3.0.2'
+info:
+ title: API Title
+ version: '1.0'
+servers:
+ - url: https://api.server.test/api
+paths:
+ /consume/qrcode/init:
+ $ref: consumeapi.yaml#/components/paths/qrcodePayInit
+ /consume/qrcode/confirm:
+ $ref: consumeapi.yaml#/components/paths/qrcodePayConfirm
+ /consume/qrcode/query/{refno}:
+ $ref: consumeapi.yaml#/components/paths/qrcodePayQuery
diff --git a/payapi/build.gradle b/payapi/build.gradle
index 3bbc883..656a319 100644
--- a/payapi/build.gradle
+++ b/payapi/build.gradle
@@ -18,10 +18,6 @@
bootJar {
enabled = true
mainClassName = payapiStartClass
-// def standalone = ""
-// if (rootProject.hasProperty("no-multi-tenant")) {
-// standalone = "-stangalone-"
-//
archiveFileName = "${project.name}-${buildVersion}.${archiveExtension.getOrElse('.jar')}"
manifest {
attributes("Payapi-Version": buildVersion,
@@ -101,6 +97,9 @@
implementation "org.thymeleaf.extras:thymeleaf-extras-springsecurity5"
+ implementation group: 'io.swagger', name: 'swagger-annotations', version: swaggerVersion
+ implementation group: 'io.springfox', name: 'springfox-swagger2', version: springfoxVersion
+
implementation "org.apache.commons:commons-lang3:${lang3Version}"
implementation "net.javacrumbs.shedlock:shedlock-spring:${shedlockVersion}"
implementation "net.javacrumbs.shedlock:shedlock-provider-redis-spring:${shedlockVersion}"
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/RFC3339DateFormat.java b/payapi/src/main/java/com/supwisdom/dlpay/RFC3339DateFormat.java
new file mode 100644
index 0000000..7ce517a
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/RFC3339DateFormat.java
@@ -0,0 +1,22 @@
+package com.supwisdom.dlpay;
+
+import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
+import com.fasterxml.jackson.databind.util.ISO8601Utils;
+
+import java.text.FieldPosition;
+import java.util.Date;
+
+
+public class RFC3339DateFormat extends ISO8601DateFormat {
+
+ private static final long serialVersionUID = 1L;
+
+ // Same as ISO8601DateFormat but serializing milliseconds.
+ @Override
+ public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
+ String value = ISO8601Utils.format(date, true);
+ toAppendTo.append(value);
+ return toAppendTo;
+ }
+
+}
\ No newline at end of file
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/ApiUtil.java b/payapi/src/main/java/com/supwisdom/dlpay/api/ApiUtil.java
new file mode 100644
index 0000000..4a0abe7
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/ApiUtil.java
@@ -0,0 +1,19 @@
+package com.supwisdom.dlpay.api;
+
+import org.springframework.web.context.request.NativeWebRequest;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class ApiUtil {
+ public static void setExampleResponse(NativeWebRequest req, String contentType, String example) {
+ try {
+ HttpServletResponse res = req.getNativeResponse(HttpServletResponse.class);
+ res.setCharacterEncoding("UTF-8");
+ res.addHeader("Content-Type", contentType);
+ res.getWriter().print(example);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/ConsumeApi.java b/payapi/src/main/java/com/supwisdom/dlpay/api/ConsumeApi.java
new file mode 100644
index 0000000..86c57a8
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/ConsumeApi.java
@@ -0,0 +1,81 @@
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (4.2.2).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+package com.supwisdom.dlpay.api;
+
+import com.supwisdom.dlpay.payapi.model.QrcodePayConfirmRequest;
+import com.supwisdom.dlpay.payapi.model.QrcodePayInitRequest;
+import io.swagger.annotations.*;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
+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.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2020-03-12T16:17:20.799+08:00[Asia/Shanghai]")
+
+@Validated
+@Api(value = "consume", description = "the consume API")
+public interface ConsumeApi {
+
+ default Optional<NativeWebRequest> getRequest() {
+ return Optional.empty();
+ }
+
+ @ApiOperation(value = "", nickname = "qrcodePayConfirm", notes = "", tags={ "pos", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "交易成功"),
+ @ApiResponse(code = 409, message = "交易正忙,稍后重试"),
+ @ApiResponse(code = 200, message = "交易失败") })
+ @RequestMapping(value = "/consume/qrcode/confirm",
+ produces = { "application/json" },
+ consumes = { "application/json" },
+ method = RequestMethod.POST)
+ default ResponseEntity<Void> qrcodePayConfirm(@ApiParam(value = "租户ID" ,required=true) @RequestHeader(value="X-Tenant-Id", required=true) String xTenantId,@ApiParam(value = "Qrcode确认" ) @Valid @RequestBody QrcodePayConfirmRequest qrcodePayConfirmRequest) {
+ return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+
+ }
+
+
+ @ApiOperation(value = "", nickname = "qrcodePayInit", notes = "", tags={ "pos", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "初始化成功"),
+ @ApiResponse(code = 200, message = "请求错误") })
+ @RequestMapping(value = "/consume/qrcode/init",
+ produces = { "application/json" },
+ consumes = { "application/json" },
+ method = RequestMethod.POST)
+ default ResponseEntity<Void> qrcodePayInit(@ApiParam(value = "租户ID" ,required=true) @RequestHeader(value="X-Tenant-Id", required=true) String xTenantId,@ApiParam(value = "QrCode 初始化" ) @Valid @RequestBody QrcodePayInitRequest qrcodePayInitRequest) {
+ return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+
+ }
+
+
+ @ApiOperation(value = "", nickname = "qrcodePayQuery", notes = "根据系统交易参考号查询流水状态", tags={ "pos", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "查询成功"),
+ @ApiResponse(code = 200, message = "查询失败") })
+ @RequestMapping(value = "/consume/qrcode/query/{refno}",
+ produces = { "application/json" },
+ method = RequestMethod.GET)
+ default ResponseEntity<Void> qrcodePayQuery(@ApiParam(value = "租户ID" ,required=true) @RequestHeader(value="X-Tenant-Id", required=true) String xTenantId,@ApiParam(value = "系统交易参考号",required=true) @PathVariable("refno") String refno) {
+ return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+
+ }
+
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/ConsumeApiController.java b/payapi/src/main/java/com/supwisdom/dlpay/api/ConsumeApiController.java
new file mode 100644
index 0000000..dc318fe
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/ConsumeApiController.java
@@ -0,0 +1,25 @@
+package com.supwisdom.dlpay.api;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.context.request.NativeWebRequest;
+import java.util.Optional;
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2020-03-12T16:09:45.966+08:00[Asia/Shanghai]")
+
+@Controller
+@RequestMapping("${openapi.aPITitle.base-path:/api}")
+public class ConsumeApiController implements ConsumeApi {
+
+ private final NativeWebRequest request;
+
+ @org.springframework.beans.factory.annotation.Autowired
+ public ConsumeApiController(NativeWebRequest request) {
+ this.request = request;
+ }
+
+ @Override
+ public Optional<NativeWebRequest> getRequest() {
+ return Optional.ofNullable(request);
+ }
+
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TAccount.java b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TAccount.java
index 7b04f82..4a06d9b 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TAccount.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TAccount.java
@@ -161,11 +161,11 @@
}
public Double getAvailbal() {
- return availbal;
+ return balance - frozebal;
}
public void setAvailbal(Double availbal) {
- this.availbal = availbal;
+ this.availbal = 0.0;
}
public Double getFrozebal() {
diff --git a/payapi/src/main/java/org/openapitools/configuration/HomeController.java b/payapi/src/main/java/org/openapitools/configuration/HomeController.java
new file mode 100644
index 0000000..2572783
--- /dev/null
+++ b/payapi/src/main/java/org/openapitools/configuration/HomeController.java
@@ -0,0 +1,19 @@
+package org.openapitools.configuration;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+
+/**
+ * Home redirection to OpenAPI api documentation
+ */
+@Controller
+public class HomeController {
+
+ @RequestMapping("/")
+ public String index() {
+ return "redirect:swagger-ui.html";
+ }
+
+
+}
diff --git a/payapi/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java b/payapi/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java
new file mode 100644
index 0000000..9754ed5
--- /dev/null
+++ b/payapi/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java
@@ -0,0 +1,71 @@
+package org.openapitools.configuration;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import org.springframework.web.util.UriComponentsBuilder;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.paths.Paths;
+import springfox.documentation.spring.web.paths.RelativePathProvider;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import javax.servlet.ServletContext;
+
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2020-03-12T16:09:45.966+08:00[Asia/Shanghai]")
+
+@Configuration
+@EnableSwagger2
+public class OpenAPIDocumentationConfig {
+
+ ApiInfo apiInfo() {
+ return new ApiInfoBuilder()
+ .title("API Title")
+ .description("No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)")
+ .license("")
+ .licenseUrl("http://unlicense.org")
+ .termsOfServiceUrl("")
+ .version("1.0")
+ .contact(new Contact("","", ""))
+ .build();
+ }
+
+ @Bean
+ public Docket customImplementation(ServletContext servletContext, @Value("${openapi.aPITitle.base-path:/v1/api}") String basePath) {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .select()
+ .apis(RequestHandlerSelectors.basePackage("com.supwisdom.dlpay.api"))
+ .build()
+ .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath))
+ .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class)
+ .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class)
+ .apiInfo(apiInfo());
+ }
+
+ class BasePathAwareRelativePathProvider extends RelativePathProvider {
+ private String basePath;
+
+ public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) {
+ super(servletContext);
+ this.basePath = basePath;
+ }
+
+ @Override
+ protected String applicationPath() {
+ return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString());
+ }
+
+ @Override
+ public String getOperationPath(String operationPath) {
+ UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/");
+ return Paths.removeAdjacentForwardSlashes(
+ uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString());
+ }
+ }
+
+}
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt
index 42ee1e4..be0b03e 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt
@@ -28,6 +28,7 @@
import org.springframework.cache.interceptor.KeyGenerator
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.context.event.ContextStartedEvent
import org.springframework.context.event.EventListener
@@ -243,6 +244,7 @@
@ServletComponentScan
@EnableAsync
@EnableRetry
+@ComponentScan(basePackages = ["com.supwisdom.dlpay", "org.openapitools.configuration"])
class PayApiApplication : SpringBootServletInitializer() {
override fun configure(builder: SpringApplicationBuilder): SpringApplicationBuilder {
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt
index 71c3189..3c03563 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt
@@ -65,7 +65,6 @@
}
dtl.befbal = account.availbal
doRecalcAccountBalance(dtl, amount, account)
- account.availbal += amount
account.balance += amount
val sameDay = DateUtil.sameDay(account.lasttranstime,
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt
index b0aefd2..6165d49 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt
@@ -90,7 +90,7 @@
userid = builder.person().person!!.userid
accountNo = builder.person().person!!.accno
userName = builder.person().person!!.accname
- befbal = builder.person().person!!.availbal
+ befbal = builder.person().person!!.balance
}
aftbal = 0.0
outtradeno = builder.outtradeno
diff --git a/payapi/src/main/resources/application.properties b/payapi/src/main/resources/application.properties
index 4c93ce7..7565c8c 100644
--- a/payapi/src/main/resources/application.properties
+++ b/payapi/src/main/resources/application.properties
@@ -49,6 +49,11 @@
###################################################
spring.redis.database=0
###################################################
+springfox.documentation.swagger.v2.path=/api-docs
+openapi.aPITitle.base-path=/payapi
+spring.jackson.date-format=com.supwisdom.dlpay.payapi.RFC3339DateFormat
+spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
+
multi-tenant.header.key=X-TENANT-ID
multi-tenant.session.name=tenant-id
multi-tenant.session.enableSessionScopedBean=false
diff --git a/settings.gradle b/settings.gradle
index c670d5a..25e20df 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -3,5 +3,6 @@
include 'payapi-sdk'
include 'payapi-common'
include 'ynrcc-agent'
+include 'payapi-spec'
include 'oauth'