From: Tang Cheng Date: Thu, 12 Mar 2020 07:55:12 +0000 (+0800) Subject: feat: 增加了 openapi spec X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=cc4299da8f5b8c9464cd2875a010f8f06fd9c14c;p=epayment%2Ffood_payapi.git feat: 增加了 openapi spec --- diff --git a/build.gradle b/build.gradle index 0e2feff3..7187f274 100644 --- a/build.gradle +++ b/build.gradle @@ -9,6 +9,7 @@ plugins { 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 @@ subprojects { 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 ee97798e..ba8d004a 100644 --- a/payapi-common/build.gradle +++ b/payapi-common/build.gradle @@ -32,6 +32,11 @@ dependencies { 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 00000000..1f0addae --- /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 00000000..51685c4f --- /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 00000000..cdb426d5 --- /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 00000000..c4bc7c96 --- /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 00000000..4d62dd55 --- /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 00000000..fea5324f --- /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 00000000..1b432bc9 --- /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 3bbc8839..656a3198 100644 --- a/payapi/build.gradle +++ b/payapi/build.gradle @@ -18,10 +18,6 @@ println("Build version: $buildVersion") 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 @@ dependencies { 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 00000000..7ce517a8 --- /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 00000000..4a0abe78 --- /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 00000000..86c57a81 --- /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 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 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 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 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 00000000..dc318fef --- /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 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 7b04f82f..4a06d9b5 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 class TAccount implements Serializable { } 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 00000000..25727830 --- /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 00000000..9754ed51 --- /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 42ee1e44..be0b03e6 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.annotation.EnableCaching 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 @@ class MyTenantJwtConfigAdapter : JwtTenantConfigAdapter { @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 71c31896..3c035636 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 @@ class AccountServiceImpl : AccountService { } 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 b0aefd24..6165d493 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 @@ class TransactionServiceImpl : TransactionService { 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 4c93ce7b..7565c8c1 100644 --- a/payapi/src/main/resources/application.properties +++ b/payapi/src/main/resources/application.properties @@ -49,6 +49,11 @@ auth.password.bcrypt.length=10 ################################################### 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 c670d5a2..25e20df1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,5 +3,6 @@ include 'payapi' include 'payapi-sdk' include 'payapi-common' include 'ynrcc-agent' +include 'payapi-spec' include 'oauth'